Module:Gas: Difference between revisions
More actions
Initial version. No infobox functionality implemented. |
Add lua methods to calculate evaporation pressure/temperature for a given temperature/pressure |
||
| Line 5: | Line 5: | ||
--GetGas(?): Try to find a gas matching the input. Returns a table containing data for that gas or throws an error. | --GetGas(?): Try to find a gas matching the input. Returns a table containing data for that gas or throws an error. | ||
--EvaporationPressureClamped(gas, Temperature(K)): Calculates the evaporation pressure for a gas. | |||
--EvaporationPressureUnclamped(gas, Temperature(K)): Calculates the evaporation pressure for a gas while ignoring curve values. | |||
--EvaporationPressure(gas, Temperature(K)): Calculates the actual evaporation pressure for a gas ingame as neither Clamped nor Unclamped values are used | |||
--EvaporationTemperatureUnclamped(gas, Pressure(kPa)): Calculates the evaporation temperature for a gas while ignoring pressure limits. | |||
--EvaporationTemperatureClamped(gas, Pressure(kPa)): Calculates the evaporation temperature for a gas. | |||
--EvaporationTemperature(gas, Pressure(kPa)[, Temperature(K)]): Currently the same as EvaporationTemperatureClamped. | |||
local GasData = mw.loadData("Module:Gas/data") | local GasData = mw.loadData("Module:Gas/data") | ||
| Line 54: | Line 61: | ||
end | end | ||
p.GetGas = GetGas | p.GetGas = GetGas | ||
local function EvaporationPressureUnclamped(gas, Temperature) -- Evaporation pressure using exponential curve | |||
return gas.A*(Temperature^Gas.B) | |||
end | |||
p.EvaporationPressureUnclamped = EvaporationPressureUnclamped | |||
local function Clamp(value, min, max) --helper function. Not sure if this should be added into the global math library. | |||
if value<min then return min end | |||
if value>max then return max end | |||
return value | |||
end | |||
local function EvaporationPressureClamped(gas, Temperature) --Evaporation pressure using stationpedia curve | |||
Temperature = Clamp(Temperature,gas.FreezingTemperature, gas.CriticalTemperature) | |||
return EvaporationPressureUnclamped(gas, Temperature) | |||
end | |||
p.EvaporationPressureClamped = EvaporationPressureClamped | |||
local function MapToScale(min, max, outMin, outMax, value) --Helper function, maps to RocketMath.MapToScale | |||
local inputRange = max-min | |||
local outputRange = outMax-outMin | |||
return (value-min) * outputRange / inputRange + outMin | |||
end | |||
local function EvaporationPressure(gas, Temperature) --Evaporation pressure using actual ingame curve | |||
if gas.State == "Liquid" and Temperature < gas.FreezingTemperature then --Frozen gases still follow EvaporationPressureClamped | |||
Temperature = math.max(gas.FreezingTemperature/2, Temperature) | |||
return MapToScale(gas.FreezingTemperature/2, gas.FreezingTemperature, GasData.ArmstrongLimit, gas.TriplePressure, Temperature) | |||
else return EvaporationPressureClamped(gas, Temperature) | |||
end | |||
end | |||
p.EvaporationPressure = EvaporationPressure | |||
local function EvaporationTemperatureUnclamped(gas, Pressure) --Evaporation temperature using exponential curve | |||
return (Pressure/gas.A) ^ (1/gas.B) | |||
end | |||
local function EvaporationTemperatureClamped(gas, Pressure) --Evaporation temperature using stationpedia curve | |||
Pressure = Clamp(Pressure, gas.TriplePressure, gas.CriticalPressure) | |||
return EvaporationTemperatureClamped(gas, Pressure) | |||
end | |||
local function Lerp(a,b,x) | |||
return a+(b-a)*Clamp(t,0,1) | |||
end | |||
--[[local function EvaporationTemperature(gas, Pressure, Temperature) -- Evaporation temperature using actual ingame rules. | |||
Temperature = Temperature or gas.Temperature --It depends on the gas's own temperature for liquids. | |||
if gas.State == "Gas" or not Temperature then | |||
return EvaporationTemperatureClamped(gas, Pressure) --placeholder, unchecked | |||
else--if gas.State == "Liquid" then | |||
if Temperature > gas.CriticalTemperature then return EvaporationTemperatureClamped(gas, Pressure) end | |||
if Temperature < gas.FreezingTemperature+1 and Temperature > gas.FreezingTemperature/2+1 then return Temperature-0.5 end | |||
local evaporationtemperature = EvaporationPressure(gas, Temperature) | |||
return Lerp(Temperature, Temperature-10, (EvaporationPressure(gas, Temperature)-Pressure)/TriplePointPressure) | |||
end | |||
error("Invalid Gas State") | |||
end--]]-- | |||
--The method above doesn't make much sense yet because it's used for calculating evaporation energy limits instead of an actual evaporation temperature. | |||
--Until it's actually used a simpler approach for evaporation(with the full one better done on an entirely separate atmospheric simulation module) may be better suited. | |||
local EvaporationTemperature = EvaporationTemperatureClamped | |||
p.EvaporationTemperature = EvaporationTemperature | |||
return p | return p | ||
Latest revision as of 20:00, 13 March 2026
Documentation for this module can be edited at Module:Gas/doc
Methods
GetGas
Use: GetGas(User input)
Returns a read-only Gas object containing information for a given gas.
If no gas is found that can match the input, throws an error.
Phase change methods
Evaporation Pressure
EvaporationPressureUnclamped
Use: EvaporationPressureClamped(gasTable, Temperature)
gasTable: a table containing information for a given gas (obtainable through GetGas)
Temperature: The current gas gemperature in kelvin
Evaluates the gas's evaporation pressure curve for a given Temperature, returning its corresponding evaporation pressure in kPa. This is just the curve function without any compensation for phase change characteristics.
EvaporationPressureClamped
Use: EvaporationPressureUnclamped(gasTable, Temperature)
gasTable: a table containing information for a given gas (obtainable through GetGas)
Temperature: The current gas gemperature in kelvin
Evaluates the gas's evaporation pressure curve for a given Temperature, returning its corresponding evaporation pressure in kPa. Unlike EvaporationPressureClamped, this first clamps the input temperature to values within the range where the gas can exist as a non-frozen liquid.
EvaporationPressure
Use: EvaporationPressure(gasTable, Temperature)
gasTable: a table containing information for a given gas (obtainable through GetGas)
Temperature: The current gas gemperature in kelvin
Evaluates the gas's evaporation pressure curve for a given Temperature, returning its corresponding evaporation pressure in kPa. Unlike the other methods, this provides additional handling to return the evaporation pressure for supercooled liquids when given a liquid as input.
Evaporation Temperature
EvaporationTemperatureUnclamped
Use: EvaporationPressureUnclamped(gasTable, Pressure)
gasTable: a table containing information for a given gas (obtainable through GetGas)
Pressure: The current gas pressure in kPa
Evaluates the gas's evaporation pressure curve for a given Pressure, returning its corresponding evaporation temperature in kelvin. This is just the curve function without any compensation for phase change characteristics.
EvaporationTemperatureClamped
Use: EvaporationTemperatureClamped(gasTable, Pressure)
gasTable: a table containing information for a given gas (obtainable through GetGas)
Pressure: The current gas pressure in kPa
Evaluates the gas's evaporation pressure curve for a given Pressure, returning its corresponding evaporation temperature in kelvin. Pressure values are clamped to the range of values the gas can exist as a non-frozen, non-supercritical liquid.
EvaporationTemperature
Use: EvaporationTemperatureClamped(gasTable, Temperature)
gasTable: a table containing information for a given gas (obtainable through GetGas)
Pressure: The current gas pressure in kPa
Evaluates the gas's evaporation pressure curve for a given Pressure, returning its corresponding evaporation temperature in kelvin. This is currently the same as EvaporationTemperatureUnclamped(gasTable, Pressure).
Objects
Gas
A table containing data for a gas. Editing these should be done through Module:Gas/data.
Fields
See Module:Gas/data/doc.
--Wikitext methods:
--Infobox(GasName): Creates an infobox for the gas type. (NYI)
--Lua methods:
--GetGas(?): Try to find a gas matching the input. Returns a table containing data for that gas or throws an error.
--EvaporationPressureClamped(gas, Temperature(K)): Calculates the evaporation pressure for a gas.
--EvaporationPressureUnclamped(gas, Temperature(K)): Calculates the evaporation pressure for a gas while ignoring curve values.
--EvaporationPressure(gas, Temperature(K)): Calculates the actual evaporation pressure for a gas ingame as neither Clamped nor Unclamped values are used
--EvaporationTemperatureUnclamped(gas, Pressure(kPa)): Calculates the evaporation temperature for a gas while ignoring pressure limits.
--EvaporationTemperatureClamped(gas, Pressure(kPa)): Calculates the evaporation temperature for a gas.
--EvaporationTemperature(gas, Pressure(kPa)[, Temperature(K)]): Currently the same as EvaporationTemperatureClamped.
local GasData = mw.loadData("Module:Gas/data")
local p = {}
local function GetGas(input)
--Attempts to get a Gas object from user input.
if input == nil then return nil end
--Frame handling
if type(input)=="table" and type(input.args)=="table" then return GetGas(p.args.Name) or GetGas(p.args[1]) or GetGas(p.args[2]) or GetGas(p.args[3]) end
--Gas handling
if type(input)=="table" and type(input.Name)=="String" and type(input.State)=="String" and type(input.MolarMass)=="number" then return input end
--Number handling
if type(input)=="number" then return GasData[input] or error("Could not find GasData for Gas number: "..input) end
--String handling
if type(input)=="string" then
-- See if there's a direct name match
if type(GasData[input])=="table" and GasData[input].Name == input then return GasData[input] end
-- search for human readable names
for k,v in pairs(GasData.HumanReadableName) do
if v==input then return GetGas(k) end
end
-- search for human readable symbols, preferring gases first
local LiquidWithSymbol
for k,v in pairs(GasData.HumanReadableSymbol) do
if v==input and GasData[k].State=="Gas" then return p.GetGas(k) end
if v==input and GasData[k].State=="Liquid" then LiquidWithSymbol = k end
end
if LiquidWithSymbol then return GetGas(LiquidWithSymbol) end
-- Hail mary: Try to find a liquid version of the gas.
if input:sub(1,6)=="Liquid" then error("Could not find GasData for gas: "..input) end --fail if we're already doing that
-- If there's a space in our name we'll probably have better luck by also using a space.
if string.match(input, " .") then return p.GetGas("Liquid "..input) else return p.GetGas("Liquid"..input) end
end
end
p.GetGas = GetGas
local function EvaporationPressureUnclamped(gas, Temperature) -- Evaporation pressure using exponential curve
return gas.A*(Temperature^Gas.B)
end
p.EvaporationPressureUnclamped = EvaporationPressureUnclamped
local function Clamp(value, min, max) --helper function. Not sure if this should be added into the global math library.
if value<min then return min end
if value>max then return max end
return value
end
local function EvaporationPressureClamped(gas, Temperature) --Evaporation pressure using stationpedia curve
Temperature = Clamp(Temperature,gas.FreezingTemperature, gas.CriticalTemperature)
return EvaporationPressureUnclamped(gas, Temperature)
end
p.EvaporationPressureClamped = EvaporationPressureClamped
local function MapToScale(min, max, outMin, outMax, value) --Helper function, maps to RocketMath.MapToScale
local inputRange = max-min
local outputRange = outMax-outMin
return (value-min) * outputRange / inputRange + outMin
end
local function EvaporationPressure(gas, Temperature) --Evaporation pressure using actual ingame curve
if gas.State == "Liquid" and Temperature < gas.FreezingTemperature then --Frozen gases still follow EvaporationPressureClamped
Temperature = math.max(gas.FreezingTemperature/2, Temperature)
return MapToScale(gas.FreezingTemperature/2, gas.FreezingTemperature, GasData.ArmstrongLimit, gas.TriplePressure, Temperature)
else return EvaporationPressureClamped(gas, Temperature)
end
end
p.EvaporationPressure = EvaporationPressure
local function EvaporationTemperatureUnclamped(gas, Pressure) --Evaporation temperature using exponential curve
return (Pressure/gas.A) ^ (1/gas.B)
end
local function EvaporationTemperatureClamped(gas, Pressure) --Evaporation temperature using stationpedia curve
Pressure = Clamp(Pressure, gas.TriplePressure, gas.CriticalPressure)
return EvaporationTemperatureClamped(gas, Pressure)
end
local function Lerp(a,b,x)
return a+(b-a)*Clamp(t,0,1)
end
--[[local function EvaporationTemperature(gas, Pressure, Temperature) -- Evaporation temperature using actual ingame rules.
Temperature = Temperature or gas.Temperature --It depends on the gas's own temperature for liquids.
if gas.State == "Gas" or not Temperature then
return EvaporationTemperatureClamped(gas, Pressure) --placeholder, unchecked
else--if gas.State == "Liquid" then
if Temperature > gas.CriticalTemperature then return EvaporationTemperatureClamped(gas, Pressure) end
if Temperature < gas.FreezingTemperature+1 and Temperature > gas.FreezingTemperature/2+1 then return Temperature-0.5 end
local evaporationtemperature = EvaporationPressure(gas, Temperature)
return Lerp(Temperature, Temperature-10, (EvaporationPressure(gas, Temperature)-Pressure)/TriplePointPressure)
end
error("Invalid Gas State")
end--]]--
--The method above doesn't make much sense yet because it's used for calculating evaporation energy limits instead of an actual evaporation temperature.
--Until it's actually used a simpler approach for evaporation(with the full one better done on an entirely separate atmospheric simulation module) may be better suited.
local EvaporationTemperature = EvaporationTemperatureClamped
p.EvaporationTemperature = EvaporationTemperature
return p