Module:Combustion: Difference between revisions
From Stationeers Community Wiki
More actions
mNo edit summary |
Evaporate liquid hypergols on combustion enthalpy calculation |
||
| (6 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
local GasData = mw.loadData("Module:Gas/data") | local GasData = mw.loadData("Module:Gas/data") | ||
local CombustionData = mw.loadData("Module:Combustion/data") | |||
local Gas = require("Module:Gas") | local Gas = require("Module:Gas") | ||
| Line 56: | Line 57: | ||
function p.GetCombustionEnergy(Fuel, Oxidizer) | function p.GetCombustionEnergy(Fuel, Oxidizer) | ||
if Fuel.Gas.IsHypergol then return Fuel.Gas.Enthalpy*Fuel.Amount end | if Fuel.Gas.IsHypergol then | ||
local LatentHeat | |||
if Fuel.Gas.State=="Liquid" then LatentHeat = Fuel.Gas.LatentHeat else LatentHeat = 0 end | |||
return (Fuel.Gas.Enthalpy-Fuel.Gas.LatentHeat)*Fuel.Amount | |||
end | |||
if not Oxidizer or not Oxidizer.Gas then Oxidizer = {Gas = Gas.GetGas("Oxygen"), Amount = 1} end | if not Oxidizer or not Oxidizer.Gas then Oxidizer = {Gas = Gas.GetGas("Oxygen"), Amount = 1} end | ||
| Line 77: | Line 83: | ||
local gas, amount, remainder = string.match(str, "^[,;:-]?%s*([%a%s]+)%s*[,;:-]?%s*(%d+)(.*)$") | local gas, amount, remainder = string.match(str, "^[,;:-]?%s*([%a%s]+)%s*[,;:-]?%s*(%d+)(.*)$") | ||
--"-Liquid Sodium Chloride , 2; Hydrochloric Acid = 1" should result in "Liquid Sodium Chloride", 2, "; Hydrochloric Acid = 1" | --"-Liquid Sodium Chloride , 2; Hydrochloric Acid = 1" should result in "Liquid Sodium Chloride", 2, "; Hydrochloric Acid = 1" | ||
if not gas then return nil end | if not gas then | ||
local match = string.match(str,"^[,;:-]?%s*([%a%s]+)%s*[,;:-]?.*") | |||
if match then return Gas.GetGas(match) else return nil end | |||
end | |||
--mw.log("Gas parsed:") | --mw.log("Gas parsed:") | ||
--mw.logObject(gas) | --mw.logObject(gas) | ||
| Line 92: | Line 101: | ||
if not frame.args.Fuel then error("Missing 'Fuel' parameter") end | if not frame.args.Fuel then error("Missing 'Fuel' parameter") end | ||
local fuel, fuelAmount = ParseInput(frame.args.Fuel) | local fuel, fuelAmount = ParseInput(frame.args.Fuel) | ||
if not fuelAmount then error("Missing quantity for 'Fuel' parameter") end | --if not fuelAmount then error("Missing quantity for 'Fuel' parameter") end | ||
local oxidizer, oxidizerAmount | local oxidizer, oxidizerAmount | ||
if not fuel.IsHypergol then | if not fuel.IsHypergol then | ||
if not frame.args.Oxidizer then error("Missing 'Oxidizer' parameter") end | if not frame.args.Oxidizer then error("Missing 'Oxidizer' parameter") end | ||
oxidizer, oxidizerAmount = ParseInput(frame.args.Oxidizer) | |||
end | end | ||
| Line 107: | Line 116: | ||
outputsCount = outputsCount + 1 | outputsCount = outputsCount + 1 | ||
local output, outputAmount = ParseInput(v) | local output, outputAmount = ParseInput(v) | ||
if not outputAmount then error ("Missing quantity for '"..k.."' parameter") end | --if not outputAmount then error ("Missing quantity for '"..k.."' parameter") end | ||
outputs[outputsCount] = {Gas = output, Amount = outputAmount} | outputs[outputsCount] = {Gas = output, Amount = outputAmount} | ||
end | end | ||
end | end | ||
-- Attempt to autofill inputs from combustion data table if they're absent | |||
mw.log ("FuelName: "..fuel.Name) | |||
if not oxidizer and not fuelAmount then fuelAmount = CombustionData[fuel.Name].FuelAmount end | |||
if oxidizer and not fuelAmount then fuelAmount = CombustionData[fuel.Name][oxidizer.Name].FuelAmount end | |||
if oxidizer and not oxidizerAmount then oxidizerAmount = CombustionData[fuel.Name][oxidizer.Name].OxidizerAmount end | |||
if outputsCount == 0 and not frame.args.DontAutofillOutputs then | |||
if not oxidizer then outputs = CombustionData[fuel.Name].Outputs end | |||
if oxidizer then outputs = CombustionData[fuel.Name][oxidizer.Name].Outputs end | |||
end | |||
return RenderCombustionTemplate(frame, {Gas = fuel, Amount = fuelAmount}, {Gas = oxidizer, Amount = oxidizerAmount}, outputs) | return RenderCombustionTemplate(frame, {Gas = fuel, Amount = fuelAmount}, {Gas = oxidizer, Amount = oxidizerAmount}, outputs) | ||
end | end | ||
return p | return p | ||
Latest revision as of 23:57, 18 March 2026
Documentation for this module may be created at Module:Combustion/doc
local GasData = mw.loadData("Module:Gas/data")
local CombustionData = mw.loadData("Module:Combustion/data")
local Gas = require("Module:Gas")
local function GetRepresentation(gas, frame)
--mw.log("GetRepresentation called. gas:")
--mw.logObject(gas)
--mw.log("Frame: ")
--mw.logObject(frame)
return frame:expandTemplate({title = "GasIcon", args = {gas.Name} }) -- Embeds a Not-yet-implemented template.
end
local p={}
local function RenderCombustionTemplate(frame, Fuel, Oxidizer, Reagents)
mw.log("RenderCombustionTemplate called. Fuel:")
mw.logObject(Fuel)
mw.log("Oxidizer:")
mw.logObject(Oxidizer)
mw.log("Reagents:")
mw.logObject(Reagents)
--TODO: Add actual formatting into a box or something.
local InputReagents = {}
local FuelRepresentation = GetRepresentation(Fuel.Gas, frame)
table.insert (InputReagents, Fuel.Amount.."x "..FuelRepresentation)
if Oxidizer and Oxidizer.Gas then
local OxidizerRepresentation = GetRepresentation(Oxidizer.Gas, frame)
table.insert (InputReagents, Oxidizer.Amount.."x "..OxidizerRepresentation)
end
local OutputReagents = {}
for n=1,#Reagents do
local ReagentRepresentation = GetRepresentation(Reagents[n].Gas, frame)
table.insert(OutputReagents, Reagents[n].Amount.."x "..ReagentRepresentation)
end
local Autoignition=""
if frame.args.ShowAutoignition then
local T = 0
if Fuel.Gas.IsHypergol then
T = Fuel.Gas.AutoignitionTemperature
else T = Fuel.Gas.AutoignitionTemperature + Oxidizer.Gas.AutoignitionOffset end
Autoignition = " (Autoignites at "..frame:expandTemplate({title="Temperature", args={T}})..")"
end
return table.concat(InputReagents, " + ").." = "..table.concat(OutputReagents, " + ")..p.FormattedCombustionEnergy(Fuel, Oxidizer)..Autoignition
end
function p.FormattedCombustionEnergy(...)
local Energy = p.GetCombustionEnergy(...)
if Energy==0 then return "" end
if Energy<0 then return " - ".. -Energy/1000 .." kJ" end
if Energy>0 then return " + ".. Energy/1000 .." kJ" end
end
function p.GetCombustionEnergy(Fuel, Oxidizer)
if Fuel.Gas.IsHypergol then
local LatentHeat
if Fuel.Gas.State=="Liquid" then LatentHeat = Fuel.Gas.LatentHeat else LatentHeat = 0 end
return (Fuel.Gas.Enthalpy-Fuel.Gas.LatentHeat)*Fuel.Amount
end
if not Oxidizer or not Oxidizer.Gas then Oxidizer = {Gas = Gas.GetGas("Oxygen"), Amount = 1} end
local TotalEnthalpy = Fuel.Gas.Enthalpy * Fuel.Amount * Oxidizer.Gas.EnthalpyMultiplier
if Fuel.Gas.State == "Liquid" then --vaporize liquid fuels
TotalEnthalpy = TotalEnthalpy - (Fuel.Gas.LatentHeat * Fuel.Amount)
end
if Oxidizer.Gas.State == "Liquid" then --vaporize liquid oxidizers
TotalEnthalpy = TotalEnthalpy - (Oxidizer.Gas.LatentHeat * Oxidizer.Amount)
end
return TotalEnthalpy
end
local function ParseInput(str)
mw.log("ParseInput called on "..str)
local gas, amount, remainder = string.match(str, "^[,;:-]?%s*([%a%s]+)%s*[,;:-]?%s*(%d+)(.*)$")
--"-Liquid Sodium Chloride , 2; Hydrochloric Acid = 1" should result in "Liquid Sodium Chloride", 2, "; Hydrochloric Acid = 1"
if not gas then
local match = string.match(str,"^[,;:-]?%s*([%a%s]+)%s*[,;:-]?.*")
if match then return Gas.GetGas(match) else return nil end
end
--mw.log("Gas parsed:")
--mw.logObject(gas)
--mw.log("Amount parsed:")
--mw.logObject(amount)
--mw.log("Remainder:")
--mw.logObject(remainder)
return Gas.GetGas(gas), amount, remainder
end
function p.Template(frame)
frame = frame:getParent(frame)
if not frame.args.Fuel then error("Missing 'Fuel' parameter") end
local fuel, fuelAmount = ParseInput(frame.args.Fuel)
--if not fuelAmount then error("Missing quantity for 'Fuel' parameter") end
local oxidizer, oxidizerAmount
if not fuel.IsHypergol then
if not frame.args.Oxidizer then error("Missing 'Oxidizer' parameter") end
oxidizer, oxidizerAmount = ParseInput(frame.args.Oxidizer)
end
local outputs = {}
local outputsCount = 0
for k,v in pairs(frame.args) do
if string.match(k, "^Output") then
outputsCount = outputsCount + 1
local output, outputAmount = ParseInput(v)
--if not outputAmount then error ("Missing quantity for '"..k.."' parameter") end
outputs[outputsCount] = {Gas = output, Amount = outputAmount}
end
end
-- Attempt to autofill inputs from combustion data table if they're absent
mw.log ("FuelName: "..fuel.Name)
if not oxidizer and not fuelAmount then fuelAmount = CombustionData[fuel.Name].FuelAmount end
if oxidizer and not fuelAmount then fuelAmount = CombustionData[fuel.Name][oxidizer.Name].FuelAmount end
if oxidizer and not oxidizerAmount then oxidizerAmount = CombustionData[fuel.Name][oxidizer.Name].OxidizerAmount end
if outputsCount == 0 and not frame.args.DontAutofillOutputs then
if not oxidizer then outputs = CombustionData[fuel.Name].Outputs end
if oxidizer then outputs = CombustionData[fuel.Name][oxidizer.Name].Outputs end
end
return RenderCombustionTemplate(frame, {Gas = fuel, Amount = fuelAmount}, {Gas = oxidizer, Amount = oxidizerAmount}, outputs)
end
return p