Two editable, saveable fuels
authorBill Kuker <bkuker@billkuker.com>
Fri, 12 Nov 2010 14:01:35 +0000 (14:01 +0000)
committerBill Kuker <bkuker@billkuker.com>
Fri, 12 Nov 2010 14:01:35 +0000 (14:01 +0000)
src/com/billkuker/rocketry/motorsim/fuel/editable/EditablePiecewiseLinearFuel.java [new file with mode: 0644]
src/com/billkuker/rocketry/motorsim/fuel/editable/EditablePiecewiseSaintRobertFuel.java [new file with mode: 0644]

diff --git a/src/com/billkuker/rocketry/motorsim/fuel/editable/EditablePiecewiseLinearFuel.java b/src/com/billkuker/rocketry/motorsim/fuel/editable/EditablePiecewiseLinearFuel.java
new file mode 100644 (file)
index 0000000..f3d2579
--- /dev/null
@@ -0,0 +1,195 @@
+package com.billkuker.rocketry.motorsim.fuel.editable;\r
+\r
+import java.net.URI;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.NoSuchElementException;\r
+import java.util.SortedMap;\r
+import java.util.TreeMap;\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.RocketScience;\r
+import com.billkuker.rocketry.motorsim.fuel.EditableCombustionProduct;\r
+import com.billkuker.rocketry.motorsim.visual.Chart;\r
+\r
+public class EditablePiecewiseLinearFuel implements Fuel{\r
+       private static final Logger log = Logger\r
+                       .getLogger(EditablePiecewiseLinearFuel.class);\r
+       private static final Amount<Pressure> ZERO_PRESSURE = Amount.valueOf(0,\r
+                       SI.PASCAL);\r
+       private static final Amount<Velocity> ZERO_VELOCITY = Amount.valueOf(0,\r
+                       RocketScience.UnitPreference\r
+                                       .getUnitPreference().getPreferredUnit(SI.METERS_PER_SECOND));\r
+\r
+       private static 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
+       \r
+       private String name = "New Linear Fuel";\r
+       private URI uri;\r
+       private double combustionEfficiency = .97;\r
+       private double densityRatio = .96;\r
+       private Amount<VolumetricDensity> density = Amount.valueOf(1889, 0, SI.KILOGRAM.divide(SI.METER.pow(3))).to(VolumetricDensity.UNIT);\r
+\r
+       \r
+       private EditableCombustionProduct product = new EditableCombustionProduct();\r
+       private SortedMap<Amount<Pressure>, Entry> entries ;\r
+\r
+       public EditablePiecewiseLinearFuel(){\r
+               clear();\r
+       }\r
+       public void add(final Amount<Pressure> p, final Amount<Velocity> r){\r
+               entries.put(p, new Entry(){{pressure = p; burnRate = r;}});\r
+       }\r
+       \r
+       @Override\r
+       public Amount<Velocity> burnRate(final Amount<Pressure> pressure) {\r
+               if ( pressure.isLessThan(ZERO_PRESSURE) )\r
+                       return ZERO_VELOCITY;\r
+               \r
+               if ( entries.size() == 1 ){\r
+                       return entries.get(entries.firstKey()).burnRate;\r
+               }\r
+               \r
+               if ( entries.containsKey(pressure) ){\r
+                       return entries.get(pressure).burnRate;\r
+               }\r
+                       \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
+               if ( ret.isLessThan(ZERO_VELOCITY) )\r
+                       return ZERO_VELOCITY;\r
+               \r
+               return ret;\r
+               \r
+       }\r
+       \r
+       public void clear(){\r
+               entries = new TreeMap<Amount<Pressure>, Entry>();\r
+               add(Amount.valueOf(0,SI.MEGA(SI.PASCAL)), ZERO_VELOCITY);\r
+       }\r
+       \r
+       @Override\r
+       public double getCombustionEfficiency() {\r
+               return combustionEfficiency;\r
+       }\r
+       \r
+\r
+       public void setCombustionEfficiency(double combustionEfficiency) {\r
+               this.combustionEfficiency = combustionEfficiency;\r
+       }\r
+       \r
+       @Override\r
+       public CombustionProduct getCombustionProduct(){\r
+               return product;\r
+       }\r
+       \r
+       public void setCombustionProduct(final CombustionProduct product){\r
+               this.product = (EditableCombustionProduct)product;\r
+       }\r
+       \r
+       @Override\r
+       public double getDensityRatio() {\r
+               return densityRatio;\r
+       }\r
+       \r
+       public void setDensityRatio(double densityRatio) {\r
+               this.densityRatio = densityRatio;\r
+       }\r
+\r
+       @Override\r
+       public Amount<VolumetricDensity> getIdealDensity() {\r
+               return density;\r
+       }\r
+       \r
+       public void setIdealDensity(Amount<VolumetricDensity> density) {\r
+               this.density = density;\r
+       }\r
+\r
+       @Override\r
+       public String getName() {\r
+               return name;\r
+       }\r
+       \r
+       public void setName(String name) {\r
+               this.name = name;\r
+       }\r
+\r
+       @Override\r
+       public URI getURI() {\r
+               return uri;\r
+       }\r
+\r
+\r
+       \r
+       public Map<Amount<Pressure>, Amount<Velocity>> getEntries() {\r
+               HashMap<Amount<Pressure>, Amount<Velocity>> ret = new HashMap<Amount<Pressure>, Amount<Velocity>>();\r
+               for ( Entry e : entries.values() )\r
+                       ret.put(e.pressure, e.burnRate);\r
+               return ret;\r
+       }\r
+       \r
+       public void setEntries(Map<Amount<Pressure>, Amount<Velocity>> in) {\r
+               clear();\r
+               for ( Map.Entry<Amount<Pressure>, Amount<Velocity>> e : in.entrySet()){\r
+                       add( e.getKey(), e.getValue());\r
+               }\r
+       }\r
+\r
+\r
+       \r
+       public static void main( String args[]) throws Exception{\r
+               EditablePiecewiseLinearFuel f = new EditablePiecewiseLinearFuel();\r
+               f.add(Amount.valueOf(0,SI.MEGA(SI.PASCAL)), Amount.valueOf(2, 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
diff --git a/src/com/billkuker/rocketry/motorsim/fuel/editable/EditablePiecewiseSaintRobertFuel.java b/src/com/billkuker/rocketry/motorsim/fuel/editable/EditablePiecewiseSaintRobertFuel.java
new file mode 100644 (file)
index 0000000..1c80761
--- /dev/null
@@ -0,0 +1,116 @@
+package com.billkuker.rocketry.motorsim.fuel.editable;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import javax.measure.quantity.Pressure;\r
+import javax.measure.quantity.VolumetricDensity;\r
+\r
+import org.jscience.physics.amount.Amount;\r
+\r
+import com.billkuker.rocketry.motorsim.fuel.EditableCombustionProduct;\r
+import com.billkuker.rocketry.motorsim.fuel.PiecewiseSaintRobertFuel;\r
+\r
+public class EditablePiecewiseSaintRobertFuel extends PiecewiseSaintRobertFuel {\r
+\r
+       @SuppressWarnings("unchecked")\r
+       private Amount<VolumetricDensity> idealDensity = (Amount<VolumetricDensity>) Amount\r
+                       .valueOf("1 g/mm^3");\r
+       \r
+       private double combustionEfficiency = 1;\r
+       private double densityRatio = 1;\r
+       private EditableCombustionProduct cp;\r
+       private String name = "New Fuel";\r
+\r
+       public EditablePiecewiseSaintRobertFuel() {\r
+               super(Type.SI);\r
+               clear();\r
+               cp = new EditableCombustionProduct();\r
+       }\r
+       \r
+       private Map<Amount<Pressure>, Double> aMap;\r
+       private Map<Amount<Pressure>, Double> nMap;\r
+       \r
+       public void clear(){\r
+               super.clear();\r
+               aMap = new HashMap<Amount<Pressure>, Double>();\r
+               nMap = new HashMap<Amount<Pressure>, Double>();\r
+       }\r
+       \r
+       public void setType(Type t){\r
+               super.setType(t);\r
+       }\r
+\r
+       public void add(Amount<Pressure> p, final double _a, final double _n) {\r
+               super.add(p, _a, _n);\r
+               aMap.put(p, _a);\r
+               nMap.put(p, _n);\r
+       }\r
+\r
+       public Amount<VolumetricDensity> getIdealDensity() {\r
+               return idealDensity;\r
+       }\r
+\r
+       public void setIdealDensity(Amount<VolumetricDensity> idealDensity) {\r
+               this.idealDensity = idealDensity;\r
+       }\r
+\r
+       public double getCombustionEfficiency() {\r
+               return combustionEfficiency;\r
+       }\r
+\r
+       public void setCombustionEfficiency(double combustionEfficiency) {\r
+               this.combustionEfficiency = combustionEfficiency;\r
+       }\r
+\r
+       public double getDensityRatio() {\r
+               return densityRatio;\r
+       }\r
+\r
+       public void setDensityRatio(double densityRatio) {\r
+               this.densityRatio = densityRatio;\r
+       }\r
+\r
+       @Override\r
+       public CombustionProduct getCombustionProduct() {\r
+               return cp;\r
+       }\r
+       \r
+       public void setCombustionProduct(final CombustionProduct product){\r
+               this.cp = (EditableCombustionProduct)product;\r
+       }\r
+\r
+       public String getName() {\r
+               return name;\r
+       }\r
+\r
+       public void setName(String name) {\r
+               this.name = name;\r
+       }\r
+\r
+       public Map<Amount<Pressure>, Double> getAMap() {\r
+               return aMap;\r
+       }\r
+\r
+       public void setAMap(Map<Amount<Pressure>, Double> aMap) {\r
+               this.aMap = aMap;\r
+               reset();\r
+       }\r
+\r
+       public Map<Amount<Pressure>, Double> getNMap() {\r
+               return nMap;\r
+       }\r
+\r
+       public void setNMap(Map<Amount<Pressure>, Double> nMap) {\r
+               this.nMap = nMap;\r
+               reset();\r
+       }\r
+\r
+       private void reset(){\r
+               if (nMap != null && aMap != null && nMap.size() == aMap.size()){\r
+                       for ( Amount<Pressure> p : aMap.keySet() ){\r
+                               add(p, aMap.get(p), nMap.get(p));\r
+                       }\r
+               }\r
+       }\r
+}
\ No newline at end of file