private void MultiplyByScalar() { float[] a = new[] { 1f, 0f, 0.01f, 2f, 10f, 0.1f, 1234f, 678.234f, }; const float b = 50f; float[] r = new[] { 50f, 0f, 0.5f, 100f, 500f, 5f, 61700f, 33911.7f, }; Span <float> s = stackalloc float[r.Length]; NumericsHelpers.Multiply(a, b, s); EqualsApprox(r, s); }
public float GetHeatCapacity(GasMixture mixture) { Span <float> tmp = stackalloc float[mixture.Moles.Length]; NumericsHelpers.Multiply(mixture.Moles, GasSpecificHeats, tmp); return(MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity)); }
private float GetHeatCapacityCalculation(float[] moles, bool immutable) { // Little hack to make space gas mixtures have heat capacity, therefore allowing them to cool down rooms. if (immutable && MathHelper.CloseTo(NumericsHelpers.HorizontalAdd(moles), 0f)) { return(Atmospherics.SpaceHeatCapacity); } Span <float> tmp = stackalloc float[moles.Length]; NumericsHelpers.Multiply(moles, GasSpecificHeats, tmp); return(MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity)); }
/// <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); } }
private void Multiply() { float[] a = new[] { 1f, 0f, 1f, 2f, 10f, 0.1f, 1234f, 678.234f, }; float[] b = new[] { 1f, 0f, 0f, 2f, 10f, 1f, 4321f, 567.123f, }; float[] r = new[] { 1f, 0f, 0f, 4f, 100f, 0.1f, 5332114f, 384642.101f, }; Span <float> s = stackalloc float[r.Length]; NumericsHelpers.Multiply(a, b, s); EqualsApprox(r, s); }