}
shouldShareAir = true;
- } else if (CompareExchange(tile.Air, enemyTile.Air) != GasCompareResult.NoExchange)
+ } else if (CompareExchange(tile, enemyTile) != GasCompareResult.NoExchange)
{
AddActiveTile(gridAtmosphere, enemyTile);
if (ExcitedGroups)
private void Archive(TileAtmosphere tile, int fireCount)
{
if (tile.Air != null)
- tile.Air.Moles.AsSpan().CopyTo(tile.MolesArchived.AsSpan());
+ tile.AirArchived = new GasMixture(tile.Air);
- tile.TemperatureArchived = tile.Temperature;
tile.ArchivedCycle = fireCount;
}
/// </summary>
public float GetHeatCapacityArchived(TileAtmosphere tile)
{
- if (tile.Air == null)
+ if (tile.AirArchived == null)
return tile.HeatCapacity;
- return GetHeatCapacityCalculation(tile.MolesArchived!, tile.Space);
+ return GetHeatCapacity(tile.AirArchived);
}
/// <summary>
/// </summary>
public float Share(TileAtmosphere tileReceiver, TileAtmosphere tileSharer, int atmosAdjacentTurfs)
{
- if (tileReceiver.Air is not {} receiver || tileSharer.Air is not {} sharer)
+ if (tileReceiver.Air is not {} receiver || tileSharer.Air is not {} sharer ||
+ tileReceiver.AirArchived == null || tileSharer.AirArchived == null)
return 0f;
- var temperatureDelta = tileReceiver.TemperatureArchived - tileSharer.TemperatureArchived;
+ var temperatureDelta = tileReceiver.AirArchived.Temperature - tileSharer.AirArchived.Temperature;
var absTemperatureDelta = Math.Abs(temperatureDelta);
var oldHeatCapacity = 0f;
var oldSharerHeatCapacity = 0f;
// Transfer of thermal energy (via changed heat capacity) between self and sharer.
if (!receiver.Immutable && newHeatCapacity > Atmospherics.MinimumHeatCapacity)
{
- receiver.Temperature = ((oldHeatCapacity * receiver.Temperature) - (heatCapacityToSharer * tileReceiver.TemperatureArchived) + (heatCapacitySharerToThis * tileSharer.TemperatureArchived)) / newHeatCapacity;
+ receiver.Temperature = ((oldHeatCapacity * receiver.Temperature) - (heatCapacityToSharer * tileReceiver.AirArchived.Temperature) + (heatCapacitySharerToThis * tileSharer.AirArchived.Temperature)) / newHeatCapacity;
}
if (!sharer.Immutable && newSharerHeatCapacity > Atmospherics.MinimumHeatCapacity)
{
- sharer.Temperature = ((oldSharerHeatCapacity * sharer.Temperature) - (heatCapacitySharerToThis * tileSharer.TemperatureArchived) + (heatCapacityToSharer * tileReceiver.TemperatureArchived)) / newSharerHeatCapacity;
+ sharer.Temperature = ((oldSharerHeatCapacity * sharer.Temperature) - (heatCapacitySharerToThis * tileSharer.AirArchived.Temperature) + (heatCapacityToSharer * tileReceiver.AirArchived.Temperature)) / newSharerHeatCapacity;
}
// Thermal energy of the system (self and sharer) is unchanged.
var moles = receiver.TotalMoles;
var theirMoles = sharer.TotalMoles;
- return (tileReceiver.TemperatureArchived * (moles + movedMoles)) - (tileSharer.TemperatureArchived * (theirMoles - movedMoles)) * Atmospherics.R / receiver.Volume;
+ return (tileReceiver.AirArchived.Temperature * (moles + movedMoles)) - (tileSharer.AirArchived.Temperature * (theirMoles - movedMoles)) * Atmospherics.R / receiver.Volume;
}
/// <summary>
/// </summary>
public float TemperatureShare(TileAtmosphere tileReceiver, TileAtmosphere tileSharer, float conductionCoefficient)
{
- if (tileReceiver.Air is not { } receiver || tileSharer.Air is not { } sharer)
+ if (tileReceiver.Air is not { } receiver || tileSharer.Air is not { } sharer ||
+ tileReceiver.AirArchived == null || tileSharer.AirArchived == null)
return 0f;
- var temperatureDelta = tileReceiver.TemperatureArchived - tileSharer.TemperatureArchived;
+ var temperatureDelta = tileReceiver.AirArchived.Temperature - tileSharer.AirArchived.Temperature;
if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider)
{
var heatCapacity = GetHeatCapacityArchived(tileReceiver);
/// </summary>
public float TemperatureShare(TileAtmosphere tileReceiver, float conductionCoefficient, float sharerTemperature, float sharerHeatCapacity)
{
- if (tileReceiver.Air is not {} receiver)
+ if (tileReceiver.Air is not {} receiver || tileReceiver.AirArchived == null)
return 0;
- var temperatureDelta = tileReceiver.TemperatureArchived - sharerTemperature;
+ var temperatureDelta = tileReceiver.AirArchived.Temperature - sharerTemperature;
if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider)
{
var heatCapacity = GetHeatCapacityArchived(tileReceiver);
private void TemperatureShareMutualSolid(TileAtmosphere tile, TileAtmosphere other, float conductionCoefficient)
{
- var deltaTemperature = (tile.TemperatureArchived - other.TemperatureArchived);
+ if (tile.AirArchived == null || other.AirArchived == null)
+ return;
+
+ var deltaTemperature = (tile.AirArchived.Temperature - other.AirArchived.Temperature);
if (MathF.Abs(deltaTemperature) > Atmospherics.MinimumTemperatureDeltaToConsider
&& tile.HeatCapacity != 0f && other.HeatCapacity != 0f)
{
public void RadiateToSpace(TileAtmosphere tile)
{
+ if (tile.AirArchived == null)
+ return;
+
// Considering 0ºC as the break even point for radiation in and out.
if (tile.Temperature > Atmospherics.T0C)
{
// Hardcoded space temperature.
- var deltaTemperature = (tile.TemperatureArchived - Atmospherics.TCMB);
+ var deltaTemperature = (tile.AirArchived.Temperature - Atmospherics.TCMB);
if ((tile.HeatCapacity > 0) && (MathF.Abs(deltaTemperature) > Atmospherics.MinimumTemperatureDeltaToConsider))
{
var heat = tile.ThermalConductivity * deltaTemperature * (tile.HeatCapacity *
[ViewVariables]
public float Temperature { get; set; } = Atmospherics.T20C;
- [ViewVariables]
- public float TemperatureArchived { get; set; } = Atmospherics.T20C;
-
[ViewVariables]
public TileAtmosphere? PressureSpecificTarget { get; set; }
[Access(typeof(AtmosphereSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
public GasMixture? Air { get; set; }
+ /// <summary>
+ /// Like Air, but a copy stored each atmos tick before tile processing takes place. This lets us update Air
+ /// in-place without affecting the results based on update order.
+ /// </summary>
+ [ViewVariables]
+ public GasMixture? AirArchived;
+
[DataField("lastShare")]
public float LastShare;
- [ViewVariables]
- public readonly float[] MolesArchived = new float[Atmospherics.AdjustedNumberOfGases];
-
GasMixture IGasMixtureHolder.Air
{
get => Air ?? new GasMixture(Atmospherics.CellVolume){ Temperature = Temperature };
GridIndex = gridIndex;
GridIndices = gridIndices;
Air = mixture;
+ AirArchived = Air != null ? Air.Clone() : null;
Space = space;
if(immutable)
NoGridTile = other.NoGridTile;
MapAtmosphere = other.MapAtmosphere;
Air = other.Air?.Clone();
- Array.Copy(other.MolesArchived, MolesArchived, MolesArchived.Length);
+ AirArchived = Air != null ? Air.Clone() : null;
}
public TileAtmosphere()