/// <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.
7. Solve for Q.
*/
return (cA.Temperature - cB.Temperature) *
- (cA.HeatCapacity * cB.HeatCapacity / (cA.HeatCapacity + cB.HeatCapacity));
+ (cA.HeatCapacity * cB.HeatCapacity / cTotal);
}
/// <summary>
/// <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>
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;
}
/// </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)
{
denominator += c.HeatCapacity;
}
+ ArgumentOutOfRangeException.ThrowIfNegativeOrZero(denominator);
+
return numerator / denominator;
}
/// </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;
/// </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)
{
totalEnergy += c.InternalEnergy;
}
+ ArgumentOutOfRangeException.ThrowIfNegativeOrZero(totalHeatCapacity);
+
var result = new HeatContainer
{
HeatCapacity = totalHeatCapacity,
/// <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);
}
/// </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;