package net.sf.openrocket.models.atmosphere; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Monitorable; import net.sf.openrocket.util.UniqueID; public class AtmosphericConditions implements Cloneable, Monitorable { /** Specific gas constant of dry air. */ public static final double R = 287.053; /** Specific heat ratio of air. */ public static final double GAMMA = 1.4; /** The standard air pressure (1.01325 bar). */ public static final double STANDARD_PRESSURE = 101325.0; /** The standard air temperature (20 degrees Celcius). */ public static final double STANDARD_TEMPERATURE = 293.15; /** Air pressure, in Pascals. */ private double pressure; /** Air temperature, in Kelvins. */ private double temperature; private int modID; /** * Construct standard atmospheric conditions. */ public AtmosphericConditions() { this(STANDARD_TEMPERATURE, STANDARD_PRESSURE); } /** * Construct specified atmospheric conditions. * * @param temperature the temperature in Kelvins. * @param pressure the pressure in Pascals. */ public AtmosphericConditions(double temperature, double pressure) { this.setTemperature(temperature); this.setPressure(pressure); this.modID = UniqueID.next(); } public double getPressure() { return pressure; } public void setPressure(double pressure) { this.pressure = pressure; this.modID = UniqueID.next(); } public double getTemperature() { return temperature; } public void setTemperature(double temperature) { this.temperature = temperature; this.modID = UniqueID.next(); } /** * Return the current density of air for dry air. * * @return the current density of air. */ public double getDensity() { return getPressure() / (R*getTemperature()); } /** * Return the current speed of sound for dry air. * <p> * The speed of sound is calculated using the expansion around the temperature 0 C * <code> c = 331.3 + 0.606*T </code> where T is in Celcius. The result is accurate * to about 0.5 m/s for temperatures between -30 and 30 C, and within 2 m/s * for temperatures between -55 and 30 C. * * @return the current speed of sound. */ public double getMachSpeed() { return 165.77 + 0.606 * getTemperature(); } /** * Return the current kinematic viscosity of the air. * <p> * The effect of temperature on the viscosity of a gas can be computed using * Sutherland's formula. In the region of -40 ... 40 degrees Celcius the effect * is highly linear, and thus a linear approximation is used in its stead. * This is divided by the result of {@link #getDensity()} to achieve the * kinematic viscosity. * * @return the current kinematic viscosity. */ public double getKinematicViscosity() { double v = 3.7291e-06 + 4.9944e-08 * getTemperature(); return v / getDensity(); } /** * Return a copy of the atmospheric conditions. */ @Override public AtmosphericConditions clone() { try { return (AtmosphericConditions) super.clone(); } catch (CloneNotSupportedException e) { throw new BugException("CloneNotSupportedException encountered!"); } } @Override public boolean equals(Object other) { if (this == other) return true; if (!(other instanceof AtmosphericConditions)) return false; AtmosphericConditions o = (AtmosphericConditions) other; return MathUtil.equals(this.pressure, o.pressure) && MathUtil.equals(this.temperature, o.temperature); } @Override public int hashCode() { return (int) (this.pressure + this.temperature*1000); } @Override public int getModID() { return modID; } @Override public String toString() { return String.format("AtmosphericConditions[T=%.2f,P=%.2f]", getTemperature(), getPressure()); } }