Add volume loading
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / BurnSummary.java
1 package com.billkuker.rocketry.motorsim;\r
2 \r
3 import javax.measure.quantity.Dimensionless;\r
4 import javax.measure.quantity.Duration;\r
5 import javax.measure.quantity.Force;\r
6 import javax.measure.quantity.Mass;\r
7 import javax.measure.quantity.Pressure;\r
8 import javax.measure.quantity.Volume;\r
9 import javax.measure.quantity.VolumetricDensity;\r
10 import javax.measure.unit.SI;\r
11 \r
12 import org.jscience.physics.amount.Amount;\r
13 \r
14 import com.billkuker.rocketry.motorsim.Burn.Interval;\r
15 \r
16 public class BurnSummary {\r
17 \r
18         Amount<RocketScience.Impulse> ns = Amount.valueOf(0,\r
19                         RocketScience.NEWTON_SECOND);\r
20 \r
21         Amount<Duration> thrustTime = Amount.valueOf(0, SI.SECOND);\r
22         Amount<Force> maxThrust = Amount.valueOf(0, SI.NEWTON);\r
23         Amount<Pressure> maxPressure = Amount.valueOf(0, SI.MEGA(SI.PASCAL));\r
24         Amount<Duration> isp;\r
25         Amount<Mass> propellantMass;\r
26         Double saftyFactor;\r
27         Double volumeLoading;\r
28         \r
29         public BurnSummary(Burn b) {\r
30                 for (Interval i : b.getData().values()) {\r
31                         ns = ns.plus(i.dt.times(i.thrust));\r
32                         if (i.thrust.isGreaterThan(Amount.valueOf(0.01, SI.NEWTON))) {\r
33                                 thrustTime = thrustTime.plus(i.dt);\r
34                         }\r
35                         if (i.thrust.isGreaterThan(maxThrust))\r
36                                 maxThrust = i.thrust;\r
37                         if (i.chamberPressure.isGreaterThan(maxPressure))\r
38                                 maxPressure = i.chamberPressure;\r
39                 }\r
40                 \r
41                 isp = ns\r
42                 .divide(b\r
43                                 .getMotor()\r
44                                 .getGrain()\r
45                                 .volume(Amount.valueOf(0, SI.MILLIMETER))\r
46                                 .times(b.getMotor()\r
47                                                 .getFuel()\r
48                                                 .getIdealDensity()\r
49                                                 .times(b.getMotor().getFuel()\r
50                                                                 .getDensityRatio())))\r
51                 .to(SI.METERS_PER_SECOND)\r
52                 .divide(Amount.valueOf(9.81,\r
53                                 SI.METERS_PER_SQUARE_SECOND)).to(SI.SECOND);\r
54 \r
55                 if ( b.getMotor().getChamber().getBurstPressure() != null )\r
56                         saftyFactor = b.getMotor().getChamber().getBurstPressure().divide(maxPressure).to(Dimensionless.UNIT).doubleValue(Dimensionless.UNIT);\r
57 \r
58                 Amount<Volume> vol = b.getMotor().getGrain().volume(Amount.valueOf(0, SI.MILLIMETER));\r
59                 Amount<VolumetricDensity> ideal = b.getMotor().getFuel().getIdealDensity();\r
60                 Amount<VolumetricDensity> actual = ideal.times(b.getMotor().getFuel().getDensityRatio());\r
61                 propellantMass = vol.times(actual).to(SI.GRAM);\r
62                 \r
63                 Amount<Volume> chamber = b.getMotor().getChamber().chamberVolume();\r
64                 volumeLoading = vol.divide(chamber).to(Dimensionless.UNIT).doubleValue(Dimensionless.UNIT);\r
65         }\r
66 \r
67         public String getRating() {\r
68                 float cnf = (float) (Math.log(ns\r
69                                 .doubleValue(RocketScience.NEWTON_SECOND) / 1.25) / Math\r
70                                 .log(2));\r
71                 int cn = (int) cnf;\r
72                 float fraction = cnf - cn;\r
73                 int percent = (int) (100 * fraction);\r
74                 char cl = (char) ((int) 'A' + cn);\r
75                 \r
76                 return percent + "% "\r
77                 + new String(new char[] { cl }) + "-"\r
78                 + Math.round(averageThrust().doubleValue(SI.NEWTON));\r
79         }\r
80 \r
81         public Double getSaftyFactor(){\r
82                 return saftyFactor;\r
83         }\r
84         \r
85         public Amount<RocketScience.Impulse> totalImpulse() {\r
86                 return ns;\r
87         }\r
88 \r
89         public Amount<Duration> thrustTime() {\r
90                 return thrustTime;\r
91         }\r
92 \r
93         public Amount<Force> maxThrust() {\r
94                 return maxThrust;\r
95         }\r
96         \r
97         public Amount<Duration> specificImpulse(){\r
98                 return isp;\r
99         }\r
100 \r
101         public Amount<Force> averageThrust() {\r
102                 Amount<Force> averageThrust = Amount.valueOf(0, SI.NEWTON);\r
103                 if (thrustTime().isGreaterThan(Amount.valueOf(0, SI.SECOND)))\r
104                         averageThrust = totalImpulse().divide(thrustTime).to(SI.NEWTON);\r
105                 return averageThrust;\r
106         }\r
107 \r
108         public Amount<Pressure> maxPressure(){\r
109                 return maxPressure;\r
110         }\r
111         \r
112         public Amount<Mass> getPropellantMass() {\r
113                 return propellantMass;\r
114         }\r
115         \r
116         public double getVolumeLoading() {\r
117                 return volumeLoading;\r
118         }\r
119 \r
120 }\r