mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-02-14 23:14:45 +01:00
Guard against div/0 for HeatContainerHelpers (#42213)
Guard against div/0 for HeatContainers
This commit is contained in:
@@ -16,9 +16,13 @@ public static partial class HeatContainerHelpers
|
||||
/// <returns>The amount of heat in joules that is needed
|
||||
/// to bring the containers to thermal equilibrium.</returns>
|
||||
/// <example>A positive value indicates heat transfer from a hot cA to a cold cB.</example>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the combined heat capacity of both containers is zero or negative.</exception>
|
||||
[PublicAPI]
|
||||
public static float EquilibriumHeatQuery(this ref HeatContainer cA, ref HeatContainer cB)
|
||||
{
|
||||
var cTotal = cA.HeatCapacity + cB.HeatCapacity;
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(cTotal);
|
||||
|
||||
/*
|
||||
The solution is derived from the following facts:
|
||||
1. Let Q be the amount of heat energy transferred from cA to cB.
|
||||
@@ -32,7 +36,7 @@ public static partial class HeatContainerHelpers
|
||||
7. Solve for Q.
|
||||
*/
|
||||
return (cA.Temperature - cB.Temperature) *
|
||||
(cA.HeatCapacity * cB.HeatCapacity / (cA.HeatCapacity + cB.HeatCapacity));
|
||||
(cA.HeatCapacity * cB.HeatCapacity / cTotal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -42,11 +46,14 @@ public static partial class HeatContainerHelpers
|
||||
/// <param name="cA">The first <see cref="HeatContainer"/> to exchange heat.</param>
|
||||
/// <param name="cB">The second <see cref="HeatContainer"/> to exchange heat with.</param>
|
||||
/// <returns>The resulting equilibrium temperature both containers will be at.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the combined heat capacity of both containers is zero or negative.</exception>
|
||||
[PublicAPI]
|
||||
public static float EquilibriumTemperatureQuery(this ref HeatContainer cA, ref HeatContainer cB)
|
||||
{
|
||||
var cTotal = cA.HeatCapacity + cB.HeatCapacity;
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(cTotal);
|
||||
// Insert the above solution for Q into T_A_final = T_A_initial - Q / C_A and rearrange the result.
|
||||
return (cA.HeatCapacity * cA.Temperature - cB.HeatCapacity * cB.Temperature) / (cA.HeatCapacity + cB.HeatCapacity);
|
||||
return (cA.HeatCapacity * cA.Temperature - cB.HeatCapacity * cB.Temperature) / cTotal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -75,6 +82,7 @@ public static partial class HeatContainerHelpers
|
||||
var tFinal = EquilibriumTemperatureQuery(ref cA, ref cB);
|
||||
cA.Temperature = tFinal;
|
||||
cB.Temperature = tFinal;
|
||||
// Guarded against div/0 in EquilibriumTemperatureQuery: totalHeatCapacity > 0.
|
||||
dQ = (tInitialA - tFinal) / cA.HeatCapacity;
|
||||
}
|
||||
|
||||
@@ -120,6 +128,7 @@ public static partial class HeatContainerHelpers
|
||||
/// </summary>
|
||||
/// <param name="cN">The array of <see cref="HeatContainer"/>s to bring into thermal equilibrium.</param>
|
||||
/// <returns>The temperature of all <see cref="HeatContainer"/>s involved after reaching thermal equilibrium.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the combined heat capacity of all containers is zero or negative.</exception>
|
||||
[PublicAPI]
|
||||
public static float EquilibriumTemperatureQuery(this HeatContainer[] cN)
|
||||
{
|
||||
@@ -161,6 +170,8 @@ public static partial class HeatContainerHelpers
|
||||
denominator += c.HeatCapacity;
|
||||
}
|
||||
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(denominator);
|
||||
|
||||
return numerator / denominator;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,16 @@ public static partial class HeatContainerHelpers
|
||||
/// </summary>
|
||||
/// <param name="cA">The first <see cref="HeatContainer"/> to merge. This will be modified to contain the merged result.</param>
|
||||
/// <param name="cB">The second <see cref="HeatContainer"/> to merge.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the combined heat capacity of both containers is zero or negative.</exception>
|
||||
[PublicAPI]
|
||||
public static void Merge(this ref HeatContainer cA, HeatContainer cB)
|
||||
{
|
||||
var combinedHeatCapacity = cA.HeatCapacity + cB.HeatCapacity;
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(combinedHeatCapacity);
|
||||
var merged = new HeatContainer
|
||||
{
|
||||
HeatCapacity = cA.HeatCapacity + cB.HeatCapacity,
|
||||
Temperature = (cA.InternalEnergy + cB.InternalEnergy) / (cA.HeatCapacity + cB.HeatCapacity)
|
||||
HeatCapacity = combinedHeatCapacity,
|
||||
Temperature = (cA.InternalEnergy + cB.InternalEnergy) / combinedHeatCapacity,
|
||||
};
|
||||
|
||||
cA = merged;
|
||||
@@ -43,6 +46,7 @@ public static partial class HeatContainerHelpers
|
||||
/// </summary>
|
||||
/// <param name="cN">The array of <see cref="HeatContainer"/>s to merge.</param>
|
||||
/// <returns>A new <see cref="HeatContainer"/> representing the merged result.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the combined heat capacity of all containers is zero or negative.</exception>
|
||||
[PublicAPI]
|
||||
public static HeatContainer Merge(this HeatContainer[] cN)
|
||||
{
|
||||
@@ -55,6 +59,8 @@ public static partial class HeatContainerHelpers
|
||||
totalEnergy += c.InternalEnergy;
|
||||
}
|
||||
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(totalHeatCapacity);
|
||||
|
||||
var result = new HeatContainer
|
||||
{
|
||||
HeatCapacity = totalHeatCapacity,
|
||||
|
||||
@@ -29,9 +29,11 @@ public static partial class HeatContainerHelpers
|
||||
/// <param name="c">The <see cref="HeatContainer"/> to query.</param>
|
||||
/// <param name="dQ">The energy in joules to add or remove.</param>
|
||||
/// <returns>The resulting temperature in kelvin after the heat change.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the heat capacity of the container is zero or negative.</exception>
|
||||
[PublicAPI]
|
||||
public static float AddHeatQuery(this ref HeatContainer c, float dQ)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(c.HeatCapacity);
|
||||
// Don't allow the temperature to go below the absolute minimum.
|
||||
return Math.Max(0f, c.Temperature + dQ / c.HeatCapacity);
|
||||
}
|
||||
@@ -42,9 +44,11 @@ public static partial class HeatContainerHelpers
|
||||
/// </summary>
|
||||
/// <param name="c">The <see cref="HeatContainer"/> to modify.</param>
|
||||
/// <param name="newHeatCapacity">The new heat capacity to set.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when the new heat capacity is zero or negative.</exception>
|
||||
[PublicAPI]
|
||||
public static void SetHeatCapacity(this ref HeatContainer c, float newHeatCapacity)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(c.HeatCapacity);
|
||||
var currentEnergy = c.InternalEnergy;
|
||||
c.HeatCapacity = newHeatCapacity;
|
||||
c.Temperature = currentEnergy / c.HeatCapacity;
|
||||
|
||||
Reference in New Issue
Block a user