Fix pipe net conservation laws (#8540)

This commit is contained in:
Leon Friedrich
2022-06-03 22:09:51 +12:00
committed by GitHub
parent a5410f9c2e
commit f5dfba9db4
3 changed files with 61 additions and 21 deletions

View File

@@ -108,6 +108,52 @@ namespace Content.Server.Atmos.EntitySystems
NumericsHelpers.Add(receiver.Moles, giver.Moles);
}
/// <summary>
/// Divides a source gas mixture into several recipient mixtures, scaled by their relative volumes. Does not
/// modify the source gas mixture. Used for pipe network splitting. Note that the total destination volume
/// may be larger or smaller than the source mixture.
/// </summary>
public void DivideInto(GasMixture source, List<GasMixture> receivers)
{
var totalVolume = 0f;
foreach (var receiver in receivers)
{
if (!receiver.Immutable)
totalVolume += receiver.Volume;
}
float? sourceHeatCapacity = null;
var buffer = new float[Atmospherics.AdjustedNumberOfGases];
foreach (var receiver in receivers)
{
if (receiver.Immutable)
continue;
var fraction = receiver.Volume / totalVolume;
// Set temperature, if necessary.
if (MathF.Abs(receiver.Temperature - source.Temperature) > Atmospherics.MinimumTemperatureDeltaToConsider)
{
// Often this divides a pipe net into new and completely empty pipe nets
if (receiver.TotalMoles == 0)
receiver.Temperature = source.Temperature;
else
{
sourceHeatCapacity ??= GetHeatCapacity(source);
var receiverHeatCapacity = GetHeatCapacity(receiver);
var combinedHeatCapacity = receiverHeatCapacity + sourceHeatCapacity.Value * fraction;
if (combinedHeatCapacity > 0f)
receiver.Temperature = (GetThermalEnergy(source, sourceHeatCapacity.Value * fraction) + GetThermalEnergy(receiver, receiverHeatCapacity)) / combinedHeatCapacity;
}
}
// transfer moles
NumericsHelpers.Multiply(source.Moles, fraction, buffer);
NumericsHelpers.Add(receiver.Moles, buffer);
}
}
/// <summary>
/// Shares gas between two gas mixtures. Part of LINDA.
/// </summary>