/// <summary> /// Cycle the volume pump moving VolumeSetting liters from the input to the output /// </summary> public override void Tick() { // Bail now if there's nothing to do. if (InputAtmosphere == null || OutputAtmosphere == null || InputAtmosphere.PressureGassesAndLiquidsInPa < 1 || VolumeSetting == 0) { return; } // Pull the mixture from the input side. GasMixture mix = InputAtmosphere.Remove(InputAtmosphere.TotalMoles * VolumeSetting / (VolumeSetting + InputAtmosphere.Volume)) ?? new GasMixture(); float work = 0; // Work done in Joules float p1 = InputAtmosphere.PressureGassesAndLiquidsInPa; // Initial Pressure float p2 = OutputAtmosphere.PressureGassesAndLiquidsInPa; // Final Pressure // If the output has a lower pressure then the input no work needs to be done and the mixture can simply be moved. if (p1 < p2) { float v1 = VolumeSetting; // Inital volume float v2; // Final volume. Not used but potentially could be if a second stage of compression INTO the Output side gets implemented. // Compression consumes energy, calculate that here work = ThermodynamicHelpers.AdiabaticPressureChange(p1, v1, p2, out v2); } // Add the consumed energy to the mixture as heat mix.AddEnergy(work); // And feed that mixture into the output OutputAtmosphere.Add(mix); this.UsedPower = work; }
/// <summary> /// Simulates the flow from the InputAtmosphere to the OutputAtmosphere (or reverse if the valve is bidirectional) over Timestep seconds. /// </summary> public override void Tick() { if (InputAtmosphere == null || OutputAtmosphere == null) { return; } // Get the input/output pressures and check if the flow is going to be reversed. float pressureIn = InputAtmosphere.PressureGassesAndLiquidsInPa; float pressureOut = OutputAtmosphere.PressureGassesAndLiquidsInPa; bool reverseFlow = pressureOut > pressureIn; if (Bidirectional && reverseFlow) { float t = pressureIn; pressureIn = pressureOut; pressureOut = t; } else if (!Bidirectional && reverseFlow) { return; // No flow in reverse } // Get the gas density of the input atmosphere, will be needed to calculate molar flow float gasDensity = ThermodynamicHelpers.MolarGasDensity( (reverseFlow ? OutputAtmosphere : InputAtmosphere).GasMixture); // Iterate the flow calculations based on how accurate the simulation should be. for (int i = 0; i < Fidelity; i++) { if (reverseFlow) { pressureIn = OutputAtmosphere.PressureGassesAndLiquidsInPa; pressureOut = InputAtmosphere.PressureGassesAndLiquidsInPa; } else { pressureIn = InputAtmosphere.PressureGassesAndLiquidsInPa; pressureOut = OutputAtmosphere.PressureGassesAndLiquidsInPa; } float massFlow = CalculateFlowRate(pressureIn, pressureOut); float moleFLow = massFlow / gasDensity; float molesToMove = moleFLow * Timestep / Fidelity; if (reverseFlow) { InputAtmosphere.Add(OutputAtmosphere.Remove(molesToMove)); } else { OutputAtmosphere.Add(InputAtmosphere.Remove(molesToMove)); } } }