1 package com.billkuker.rocketry.motorsim.grain;
\r
3 import java.awt.BasicStroke;
\r
4 import java.awt.Color;
\r
5 import java.awt.Graphics2D;
\r
6 import java.awt.Rectangle;
\r
7 import java.awt.Shape;
\r
8 import java.awt.geom.Ellipse2D;
\r
9 import java.awt.geom.Rectangle2D;
\r
11 import javax.measure.quantity.Area;
\r
12 import javax.measure.quantity.Length;
\r
13 import javax.measure.quantity.Volume;
\r
14 import javax.measure.unit.SI;
\r
16 import org.jscience.physics.amount.Amount;
\r
18 import com.billkuker.rocketry.motorsim.Grain;
\r
19 import com.billkuker.rocketry.motorsim.validation.Validating;
\r
20 import com.billkuker.rocketry.motorsim.validation.ValidationException;
\r
22 public class CoredCylindricalGrain implements Grain, Validating {
\r
24 private Amount<Length> length, oD, iD;
\r
25 private boolean oInh = true, iInh = false, eInh = false;
\r
27 public CoredCylindricalGrain() {
\r
31 public void inhibit(boolean in, boolean out, boolean end){
\r
38 public Amount<Area> surfaceArea(Amount<Length> regression) {
\r
39 Amount<Length> zero = Amount.valueOf(0, SI.MILLIMETER);
\r
41 //Calculated regressed length
\r
42 Amount<Length> cLength = length;
\r
44 cLength = cLength.minus(regression.times(2));
\r
47 //Calculate regressed iD
\r
48 Amount<Length> cID = iD;
\r
50 cID = iD.plus(regression.times(2));
\r
53 //Calculate regressed oD
\r
54 Amount<Length> cOD = oD;
\r
56 cOD = oD.minus(regression.times(2));
\r
59 if ( cID.isGreaterThan(cOD) )
\r
60 return Amount.valueOf(0, SI.SQUARE_METRE);
\r
61 if ( cOD.isLessThan(cID) )
\r
62 return Amount.valueOf(0, SI.SQUARE_METRE);
\r
63 if ( cLength.isLessThan(zero) )
\r
64 return Amount.valueOf(0, SI.SQUARE_METRE);
\r
66 Amount<Area> inner = cID.times(Math.PI).times(cLength).to(SI.SQUARE_METRE);
\r
68 Amount<Area> outer = cOD.times(Math.PI).times(cLength).to(SI.SQUARE_METRE);
\r
70 Amount<Area> ends = (cOD.divide(2).pow(2).times(Math.PI)).minus(cID.divide(2).pow(2).times(Math.PI)).times(2).to(SI.SQUARE_METRE);
\r
72 Amount<Area> total = inner.times(iInh?0:1).plus(outer.times(oInh?0:1)).plus(ends.times(eInh?0:1));
\r
78 public Amount<Volume> volume(Amount<Length> regression) {
\r
79 Amount<Length> zero = Amount.valueOf(0, SI.MILLIMETER);
\r
81 //Calculated regressed length
\r
82 Amount<Length> cLength = length;
\r
84 cLength = cLength.minus(regression.times(2));
\r
87 //Calculate regressed iD
\r
88 Amount<Length> cID = iD;
\r
90 cID = iD.plus(regression.times(2));
\r
93 //Calculate regressed oD
\r
94 Amount<Length> cOD = oD;
\r
96 cOD = oD.minus(regression.times(2));
\r
99 if ( cID.isGreaterThan(cOD) )
\r
100 return Amount.valueOf(0, SI.CUBIC_METRE);
\r
101 if ( cOD.isLessThan(cID) )
\r
102 return Amount.valueOf(0, SI.CUBIC_METRE);
\r
103 if ( cLength.isLessThan(zero) )
\r
104 return Amount.valueOf(0, SI.CUBIC_METRE);
\r
107 Amount<Area> end = (cOD.divide(2).pow(2).times(Math.PI)).minus(cID.divide(2).pow(2).times(Math.PI)).to(SI.SQUARE_METRE);
\r
109 return end.times(cLength).to(SI.CUBIC_METRE);
\r
112 public void setLength(Amount<Length> length) {
\r
113 this.length = length;
\r
116 public void setOD(Amount<Length> od) {
\r
120 public void setID(Amount<Length> id) {
\r
124 public void checkValidity() throws ValidationException{
\r
125 if ( iD.equals(Amount.ZERO) )
\r
126 throw new ValidationException(this, "Invalid iD");
\r
127 if ( oD.equals(Amount.ZERO) )
\r
128 throw new ValidationException(this, "Invalid oD");
\r
129 if ( length.equals(Amount.ZERO) )
\r
130 throw new ValidationException(this, "Invalid Length");
\r
131 if ( iD.isGreaterThan(oD) )
\r
132 throw new ValidationException(this, "iD > oD");
\r
134 if ( iInh && oInh && eInh )
\r
135 throw new ValidationException(this, "No exposed grain surface");
\r
140 public Amount<Length> webThickness() {
\r
141 Amount<Length> radial = null;
\r
142 if ( !iInh && !oInh )
\r
143 radial = oD.minus(iD).divide(4); //Outer and inner exposed
\r
144 else if ( !iInh || !oInh )
\r
145 radial = oD.minus(iD).divide(2); //Outer or inner exposed
\r
147 Amount<Length> axial = null;
\r
150 axial = length.divide(2);
\r
152 if ( axial == null )
\r
154 if ( radial == null )
\r
156 if ( radial.isLessThan(axial) )
\r
161 public Amount<Length> getLength() {
\r
165 public Amount<Length> getOD() {
\r
169 public Amount<Length> getID() {
\r
174 public java.awt.geom.Area getCrossSection(Amount<Length> regression){
\r
175 double rmm = regression.doubleValue(SI.MILLIMETER);
\r
176 double oDmm = oD.doubleValue(SI.MILLIMETER);
\r
177 double iDmm = iD.doubleValue(SI.MILLIMETER);
\r
184 Shape oDs = new Ellipse2D.Double(-oDmm/2.0, -oDmm/2.0, oDmm, oDmm);
\r
185 Shape iDs = new Ellipse2D.Double(-iDmm/2.0, -iDmm/2.0, iDmm, iDmm);
\r
187 java.awt.geom.Area a = new java.awt.geom.Area(oDs);
\r
188 a.subtract(new java.awt.geom.Area(iDs));
\r
192 public java.awt.geom.Area getSideView(Amount<Length> regression){
\r
193 double rmm = regression.doubleValue(SI.MILLIMETER);
\r
194 double oDmm = oD.doubleValue(SI.MILLIMETER);
\r
195 double iDmm = iD.doubleValue(SI.MILLIMETER);
\r
196 double lmm = length.doubleValue(SI.MILLIMETER);
\r
205 java.awt.geom.Area a = new java.awt.geom.Area();
\r
206 a.add( new java.awt.geom.Area(new Rectangle2D.Double(-oDmm/2,-lmm/2,oDmm, lmm)));
\r
207 a.subtract( new java.awt.geom.Area(new Rectangle2D.Double(-iDmm/2,-lmm/2,iDmm, lmm)));
\r