--- /dev/null
+package com.billkuker.rocketry.motorsim.fuel;\r
+\r
+import javax.measure.quantity.Temperature;\r
+import javax.measure.unit.SI;\r
+\r
+import org.jscience.physics.amount.Amount;\r
+\r
+import com.billkuker.rocketry.motorsim.Fuel;\r
+import com.billkuker.rocketry.motorsim.RocketScience.MolarWeight;\r
+\r
+public class EditableCombustionProduct implements Fuel.CombustionProduct{\r
+ private Amount<MolarWeight> effectiveMolarWeight = Amount.valueOf("41.98 kg/kmol").to(MolarWeight.UNIT);;\r
+ private Amount<Temperature> idealCombustionTemperature = Amount.valueOf(1720, SI.KELVIN);;\r
+ private double ratioOfSpecificHeats = 1.133;\r
+ private double ratioOfSpecificHeats2Phase = 1.044;\r
+ public Amount<MolarWeight> getEffectiveMolarWeight() {\r
+ return effectiveMolarWeight;\r
+ }\r
+ public void setEffectiveMolarWeight(Amount<MolarWeight> effectiveMolarWeight) {\r
+ this.effectiveMolarWeight = effectiveMolarWeight;\r
+ }\r
+ public Amount<Temperature> getIdealCombustionTemperature() {\r
+ return idealCombustionTemperature;\r
+ }\r
+ public void setIdealCombustionTemperature(\r
+ Amount<Temperature> idealCombustionTemperature) {\r
+ this.idealCombustionTemperature = idealCombustionTemperature;\r
+ }\r
+ public double getRatioOfSpecificHeats() {\r
+ return ratioOfSpecificHeats;\r
+ }\r
+ public void setRatioOfSpecificHeats(double ratioOfSpecificHeats) {\r
+ this.ratioOfSpecificHeats = ratioOfSpecificHeats;\r
+ }\r
+ public double getRatioOfSpecificHeats2Phase() {\r
+ return ratioOfSpecificHeats2Phase;\r
+ }\r
+ public void setRatioOfSpecificHeats2Phase(double ratioOfSpecificHeats2Phase) {\r
+ this.ratioOfSpecificHeats2Phase = ratioOfSpecificHeats2Phase;\r
+ }\r
+}
\ No newline at end of file
package com.billkuker.rocketry.motorsim.fuel;\r
\r
import javax.measure.quantity.Pressure;\r
-import javax.measure.quantity.Temperature;\r
import javax.measure.quantity.VolumetricDensity;\r
import javax.measure.unit.SI;\r
\r
import org.jscience.physics.amount.Amount;\r
\r
-import com.billkuker.rocketry.motorsim.Fuel;\r
-import com.billkuker.rocketry.motorsim.RocketScience.MolarWeight;\r
\r
//TODO Implement MotorPart\r
public class EditableFuel extends SaintRobertFuel {\r
CombustionProduct combustionProduct = new EditableCombustionProduct();\r
private SaintRobertFuel.Type type = SaintRobertFuel.Type.NONSI;\r
\r
- public static class EditableCombustionProduct implements Fuel.CombustionProduct{\r
- private Amount<MolarWeight> effectiveMolarWeight = Amount.valueOf("41.98 kg/kmol").to(MolarWeight.UNIT);;\r
- private Amount<Temperature> idealCombustionTemperature = Amount.valueOf(1720, SI.KELVIN);;\r
- private double ratioOfSpecificHeats = 1.133;\r
- private double ratioOfSpecificHeats2Phase = 1.044;\r
- public Amount<MolarWeight> getEffectiveMolarWeight() {\r
- return effectiveMolarWeight;\r
- }\r
- public void setEffectiveMolarWeight(Amount<MolarWeight> effectiveMolarWeight) {\r
- this.effectiveMolarWeight = effectiveMolarWeight;\r
- }\r
- public Amount<Temperature> getIdealCombustionTemperature() {\r
- return idealCombustionTemperature;\r
- }\r
- public void setIdealCombustionTemperature(\r
- Amount<Temperature> idealCombustionTemperature) {\r
- this.idealCombustionTemperature = idealCombustionTemperature;\r
- }\r
- public double getRatioOfSpecificHeats() {\r
- return ratioOfSpecificHeats;\r
- }\r
- public void setRatioOfSpecificHeats(double ratioOfSpecificHeats) {\r
- this.ratioOfSpecificHeats = ratioOfSpecificHeats;\r
- }\r
- public double getRatioOfSpecificHeats2Phase() {\r
- return ratioOfSpecificHeats2Phase;\r
- }\r
- public void setRatioOfSpecificHeats2Phase(double ratioOfSpecificHeats2Phase) {\r
- this.ratioOfSpecificHeats2Phase = ratioOfSpecificHeats2Phase;\r
- }\r
- }\r
- \r
public EditableFuel() {\r
super(SaintRobertFuel.Type.NONSI);\r
}\r
--- /dev/null
+package com.billkuker.rocketry.motorsim.fuel;\r
+\r
+import java.net.URI;\r
+import java.util.NoSuchElementException;\r
+import java.util.SortedMap;\r
+import java.util.TreeMap;\r
+\r
+\r
+import javax.measure.quantity.Dimensionless;\r
+import javax.measure.quantity.Pressure;\r
+import javax.measure.quantity.Velocity;\r
+import javax.measure.quantity.VolumetricDensity;\r
+import javax.measure.unit.SI;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.jscience.physics.amount.Amount;\r
+\r
+import com.billkuker.rocketry.motorsim.Fuel;\r
+import com.billkuker.rocketry.motorsim.visual.Chart;\r
+\r
+public class PiecewiseLinearFuel implements Fuel{\r
+ private static final Logger log = Logger.getLogger(PiecewiseLinearFuel.class);\r
+ \r
+ private String name;\r
+ private URI uri;\r
+ private Amount<VolumetricDensity> density;\r
+ private float densityRatio;\r
+ private float combustionEfficiency;\r
+ \r
+ private class Entry implements Comparable<Entry>{\r
+ Amount<Pressure> pressure;\r
+ Amount<Velocity> burnRate;\r
+ @Override\r
+ public int compareTo(Entry o) {\r
+ if ( o.pressure.approximates(pressure) )\r
+ return 0;\r
+ return o.pressure.isGreaterThan(pressure)?-1:1;\r
+ }\r
+ }\r
+ \r
+ private SortedMap<Amount<Pressure>, Entry> entries = new TreeMap<Amount<Pressure>, Entry>();\r
+ \r
+ protected void add(final Amount<Pressure> p, final Amount<Velocity> r){\r
+ entries.put(p, new Entry(){{pressure = p; burnRate = r;}});\r
+ }\r
+ \r
+ public PiecewiseLinearFuel(){\r
+ add(Amount.valueOf(-1,SI.MEGA(SI.PASCAL)), Amount.valueOf(0, SI.METERS_PER_SECOND));\r
+ add(Amount.valueOf(0,SI.MEGA(SI.PASCAL)), Amount.valueOf(0, SI.METERS_PER_SECOND));\r
+ }\r
+\r
+ @Override\r
+ public String getName() {\r
+ return name;\r
+ }\r
+\r
+ @Override\r
+ public URI getURI() {\r
+ return uri;\r
+ }\r
+\r
+ @Override\r
+ public Amount<VolumetricDensity> getIdealDensity() {\r
+ return density;\r
+ }\r
+\r
+ @Override\r
+ public Amount<Velocity> burnRate(Amount<Pressure> pressure) {\r
+ Entry low = null;\r
+ low = entries.get(entries.headMap(pressure).lastKey());\r
+ Entry high = null;\r
+ try {\r
+ high = entries.get(entries.tailMap(pressure).firstKey());\r
+ } catch ( NoSuchElementException e ){\r
+ log.warn("Pressure " + pressure + " is outside of expiermental range for " + this.getName());\r
+ high = low;\r
+ low = entries.get(entries.headMap(low.pressure).lastKey());\r
+ }\r
+ \r
+ Amount<Pressure> lowToHigh = high.pressure.minus(low.pressure);\r
+ Amount<Pressure> lowToTarget = pressure.minus(low.pressure);\r
+ Amount<Dimensionless> frac = lowToTarget.divide(lowToHigh).to(Dimensionless.UNIT);\r
+ \r
+ Amount<Velocity> vdiff = high.burnRate.minus(low.burnRate);\r
+ Amount<Velocity> ret = low.burnRate.plus(vdiff.times(frac));\r
+ \r
+ return ret;\r
+ \r
+ }\r
+\r
+ @Override\r
+ public CombustionProduct getCombustionProduct(){\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public double getDensityRatio() {\r
+ return densityRatio;\r
+ }\r
+\r
+ @Override\r
+ public double getCombustionEfficiency() {\r
+ return combustionEfficiency;\r
+ }\r
+\r
+ public static void main( String args[]) throws Exception{\r
+ PiecewiseLinearFuel f = new PiecewiseLinearFuel();\r
+ f.add(Amount.valueOf(0,SI.MEGA(SI.PASCAL)), Amount.valueOf(0, SI.METERS_PER_SECOND));\r
+ f.add(Amount.valueOf(2,SI.MEGA(SI.PASCAL)), Amount.valueOf(2, SI.METERS_PER_SECOND));\r
+ f.add(Amount.valueOf(4,SI.MEGA(SI.PASCAL)), Amount.valueOf(1, SI.METERS_PER_SECOND));\r
+ f.add(Amount.valueOf(10,SI.MEGA(SI.PASCAL)), Amount.valueOf(3, SI.METERS_PER_SECOND));\r
+ f.add(Amount.valueOf(20,SI.MEGA(SI.PASCAL)), Amount.valueOf(4, SI.METERS_PER_SECOND));\r
+ Chart<Pressure, Velocity> burnRate = new Chart<Pressure, Velocity>(\r
+ SI.MEGA(SI.PASCAL),\r
+ SI.METERS_PER_SECOND,\r
+ f,\r
+ "burnRate");\r
+ burnRate.setDomain(\r
+ burnRate.new IntervalDomain(\r
+ Amount.valueOf(0, SI.MEGA(SI.PASCAL)),\r
+ Amount.valueOf(11, SI.MEGA(SI.PASCAL)),\r
+ 200\r
+ ));\r
+ \r
+ burnRate.show();\r
+ }\r
+}\r