From ef4a740a029c34d79b3174ba673704a9672b9e28 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Thu, 24 Jul 2014 17:36:57 -0400 Subject: [PATCH] Adds entropy, thermal energy procs to new gas mix --- .../components/binary_devices/pump.dm | 6 ++-- .../components/unary/vent_pump.dm | 8 ++--- code/ZAS/Gas.dm | 27 +++++++++----- code/ZAS/_gas_mixture_xgm.dm | 36 +++++++++++++++++++ code/ZAS/_xgm_gas_data.dm | 6 +++- code/game/machinery/spaceheater.dm | 2 +- 6 files changed, 66 insertions(+), 19 deletions(-) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index e25d835aa6e..50c20337d81 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -77,13 +77,11 @@ Thus, the two variables affect pump operation are set in New(): var/pressure_delta = target_pressure - sink.return_pressure() //Calculate necessary moles to transfer using PV=nRT - if(pressure_delta > 0.01 && (source.total_moles() > 0) && (source.temperature > 0 || sink.temperature > 0)) + if(pressure_delta > 0.01 && (source.total_moles > 0) && (source.temperature > 0 || sink.temperature > 0)) //Figure out how much gas to transfer var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature var/output_volume = sink.volume - if (network2 && network2.air_transient) - output_volume = network2.air_transient.volume //use the network volume if we can get it //Return the number of moles that would have to be transfered to bring sink to the target pressure var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) @@ -98,7 +96,7 @@ Thus, the two variables affect pump operation are set in New(): var/power_draw = specific_power*transfer_moles var/datum/gas_mixture/removed = source.remove(transfer_moles) - last_flow_rate = (removed.total_moles()/(removed.total_moles() + source.total_moles()))*source.volume + last_flow_rate = (removed.total_moles/(removed.total_moles + source.total_moles))*source.volume if (power_draw > 0) sink.add_thermal_energy(power_draw) diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 56d9384c13e..01b26541013 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -146,8 +146,8 @@ var/datum/gas_mixture/environment = loc.return_air() var/environment_pressure = environment.return_pressure() + if(air_contents.temperature == 0 && environment.temperature == 0) - process_broadcast_status() return 0 var/pressure_delta = DEFAULT_PRESSURE_DELTA @@ -173,8 +173,6 @@ pressure_delta = min(pressure_delta, internal_pressure_bound - air_contents.return_pressure()) //increasing the pressure here var/output_volume = air_contents.volume - if (network && network.air_transient) - output_volume = network.air_transient.volume //use the network volume if we can get it var/air_temperature = air_contents.temperature? air_contents.temperature : environment.temperature var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) @@ -189,7 +187,7 @@ return 1 /obj/machinery/atmospherics/unary/vent_pump/proc/transfer_gas(datum/gas_mixture/source, datum/gas_mixture/sink, var/transfer_moles) - if(source.total_moles() == 0) + if(source.total_moles == 0) update_use_power(0) return @@ -204,7 +202,7 @@ if (isnull(removed)) //not sure why this would happen, but it does at the very beginning of the game return - last_flow_rate = (removed.total_moles()/(removed.total_moles() + source.total_moles()))*source.volume + last_flow_rate = (removed.total_moles/(removed.total_moles + source.total_moles))*source.volume var/power_draw = specific_power*transfer_moles if (power_draw > 0) diff --git a/code/ZAS/Gas.dm b/code/ZAS/Gas.dm index 66a996457a7..0f3faa09b49 100644 --- a/code/ZAS/Gas.dm +++ b/code/ZAS/Gas.dm @@ -1,24 +1,32 @@ /xgm_gas/oxygen id = "oxygen" name = "Oxygen" - specific_heat = 20 + specific_heat = 20 // J/(mol*K) + molar_mass = 0.032 // kg/mol flags = XGM_GAS_OXIDIZER /xgm_gas/nitrogen id = "nitrogen" name = "Nitrogen" - specific_heat = 20 + specific_heat = 20 // J/(mol*K) + molar_mass = 0.028 // kg/mol /xgm_gas/carbon_dioxide id = "carbon_dioxide" name = "Carbon Dioxide" - specific_heat = 30 + specific_heat = 30 // J/(mol*K) + molar_mass = 0.044 // kg/mol /xgm_gas/phoron id = "phoron" name = "Phoron" - specific_heat = 200 + specific_heat = 200 // J/(mol*K) + + //Hypothetical group 14 (same as carbon), period 8 element. + //Using multiplicity rule, it's atomic number is 162 + //and following a N/Z ratio of 1.5, the molar mass of a monatomic gas is: + molar_mass = 0.405 // kg/mol tile_overlay = "phoron" overlay_limit = 0.7 @@ -27,19 +35,22 @@ /xgm_gas/volatile_fuel id = "volatile_fuel" name = "Volatile Fuel" - specific_heat = 30 + specific_heat = 253 // J/(mol*K) C8H18 gasoline. Isobaric, but good enough. + molar_mass = 0.114 // kg/mol. same. flags = XGM_GAS_FUEL /xgm_gas/sleeping_agent id = "sleeping_agent" name = "Sleeping Agent" - specific_heat = 40 + specific_heat = 40 // J/(mol*K) + molar_mass = 0.044 // kg/mol. N2O tile_overlay = "sleeping_agent" overlay_limit = 1 /xgm_gas/oxygen_agent_b id = "oxygen_agent_b" - name = "Oxygen Agent-B" - specific_heat = 300 + name = "Oxygen Agent-B" //what is this? + specific_heat = 300 // J/(mol*K) + molar_mass = 0.032 // kg/mol diff --git a/code/ZAS/_gas_mixture_xgm.dm b/code/ZAS/_gas_mixture_xgm.dm index a60fc0bc09d..e0639508358 100644 --- a/code/ZAS/_gas_mixture_xgm.dm +++ b/code/ZAS/_gas_mixture_xgm.dm @@ -89,6 +89,42 @@ for(var/g in gas) . += gas_data.specific_heat[g] * gas[g] +//Adds or removes thermal energy +/datum/gas_mixture/proc/add_thermal_energy(var/thermal_energy) + var/heat_capacity = heat_capacity() + if (thermal_energy < 0) + var/thermal_energy_limit = -(temperature - TCMB)*heat_capacity //ensure temperature does not go below TCMB + thermal_energy = max( thermal_energy, thermal_energy_limit ) + temperature += thermal_energy/heat_capacity + return thermal_energy + +//Returns the thermal energy change required to get to a new temperature +/datum/gas_mixture/proc/get_thermal_energy_change(var/new_temperature) + return heat_capacity()*(new_temperature - temperature) + +//Technically vacuum doesn't have a specific entropy. Just use a really big number (infinity would be ideal) here so that it's easy to add gas to vacuum and hard to take gas out. +#define SPECIFIC_ENTROPY_VACUUM 15000 + +//Returns the ideal gas specific entropy of the whole mix +/datum/gas_mixture/proc/specific_entropy() + if (!gas.len || total_moles == 0) + return SPECIFIC_ENTROPY_VACUUM + + . = 0 + for(var/g in gas) + . += specific_entropy_gas(g) + . /= total_moles + +//Returns the ideal gas specific entropy of a specific gas in the mix +/datum/gas_mixture/proc/specific_entropy_gas(var/gasid) + if (!(gasid in gas) || total_moles == 0) + return SPECIFIC_ENTROPY_VACUUM //that gas isn't here + + var/ratio = gas[gasid] / total_moles + var/molar_mass = gas_data.molar_mass[gasid] + var/specific_heat = gas_data.specific_heat[gasid] + return R_IDEAL_GAS_EQUATION * ratio * ( log( IDEAL_GAS_ENTROPY_CONSTANT * volume / gas[gasid] * sqrt( ( molar_mass * specific_heat * temperature ) ** 3 ) + 1 ) + 5/2 ) + //Updates the total_moles count and trims any empty gases. /datum/gas_mixture/proc/update_values() total_moles = 0 diff --git a/code/ZAS/_xgm_gas_data.dm b/code/ZAS/_xgm_gas_data.dm index ee33a4d57f3..fd732f9d7cd 100644 --- a/code/ZAS/_xgm_gas_data.dm +++ b/code/ZAS/_xgm_gas_data.dm @@ -7,6 +7,8 @@ var/list/name = list() //Specific heat of the gas. Used for calculating heat capacity. var/list/specific_heat = list() + //Molar mass of the gas. Used for calculating specific entropy. + var/list/molar_mass = list() //Tile overlays. /images, created from references to 'icons/effects/tile_effects.dmi' var/list/tile_overlay = list() //Overlay limits. There must be at least this many moles for the overlay to appear. @@ -17,7 +19,8 @@ /xgm_gas var/id = "" var/name = "Unnamed Gas" - var/specific_heat = 20 + var/specific_heat = 20 // J/(mol*K) + var/molar_mass = 0.032 // kg/mol var/tile_overlay = null var/overlay_limit = null @@ -35,6 +38,7 @@ gas_data.gases += gas.id gas_data.name[gas.id] = gas.name gas_data.specific_heat[gas.id] = gas.specific_heat + gas_data.molar_mass[gas.id] = gas.molar_mass if(gas.tile_overlay) gas_data.tile_overlay[gas.id] = image('icons/effects/tile_effects.dmi', gas.tile_overlay, FLY_LAYER) if(gas.overlay_limit) gas_data.overlay_limit[gas.id] = gas.overlay_limit gas_data.flags[gas.id] = gas.flags diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index c30b6b88f68..84652ae3590 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -170,7 +170,7 @@ var/datum/gas_mixture/env = L.return_air() if(env.temperature != set_temperature + T0C) - var/transfer_moles = 0.25 * env.total_moles() + var/transfer_moles = 0.25 * env.total_moles var/datum/gas_mixture/removed = env.remove(transfer_moles)