/// <summary> /// Pump gas from this mixture to the output mixture. /// Amount depends on target pressure. /// </summary> /// <param name="mixture">The mixture to pump the gas from</param> /// <param name="output">The mixture to pump the gas to</param> /// <param name="targetPressure">The target pressure to reach</param> /// <returns>Whether we could pump air to the output or not</returns> public bool PumpGasTo(GasMixture mixture, GasMixture output, float targetPressure) { var outputStartingPressure = output.Pressure; var pressureDelta = targetPressure - outputStartingPressure; if (pressureDelta < 0.01) { // No need to pump gas, we've reached the target. return(false); } if (!(mixture.TotalMoles > 0) || !(mixture.Temperature > 0)) { return(false); } // We calculate the necessary moles to transfer with the ideal gas law. var transferMoles = pressureDelta * output.Volume / (mixture.Temperature * Atmospherics.R); // And now we transfer the gas. var removed = mixture.Remove(transferMoles); Merge(output, removed); return(true); }
/// <summary> /// Releases gas from this mixture to the output mixture. /// If the output mixture is null, then this is being released into space. /// It can't transfer air to a mixture with higher pressure. /// </summary> public bool ReleaseGasTo(GasMixture mixture, GasMixture?output, float targetPressure) { var outputStartingPressure = output?.Pressure ?? 0; var inputStartingPressure = mixture.Pressure; if (outputStartingPressure >= MathF.Min(targetPressure, inputStartingPressure - 10)) { // No need to pump gas if the target is already reached or input pressure is too low. // Need at least 10 kPa difference to overcome friction in the mechanism. return(false); } if (!(mixture.TotalMoles > 0) || !(mixture.Temperature > 0)) { return(false); } // We calculate the necessary moles to transfer with the ideal gas law. var pressureDelta = MathF.Min(targetPressure - outputStartingPressure, (inputStartingPressure - outputStartingPressure) / 2f); var transferMoles = pressureDelta * (output?.Volume ?? Atmospherics.CellVolume) / (mixture.Temperature * Atmospherics.R); // And now we transfer the gas. var removed = mixture.Remove(transferMoles); if (output != null) { Merge(output, removed); } return(true); }