commit the work-in-progress drag calculations, including creating TubeCalc for calculations common to LaunchLugs and TubeFinSets
This commit is contained in:
parent
2c4ebabaa1
commit
4477d9226e
@ -1756,6 +1756,9 @@ Warning.TUMBLE_UNDER_THRUST = Stage began to tumble under thrust.
|
||||
Warning.EVENT_AFTER_LANDING = Flight Event occurred after landing:
|
||||
Warning.ZERO_LENGTH_BODY = Zero length bodies may not result in accurate simulations.
|
||||
Warning.ZERO_RADIUS_BODY = Zero length bodies may not result in accurate simulations.
|
||||
Warning.TUBE_STABILITY = Tube fin stability calculations may not be accurate.
|
||||
Warning.TUBE_SEPARATION = Space between tube fins may not result in accurate simulations.
|
||||
Warning.TUBE_OVERLAP = Overlapping tube fins may not result in accurate simulations.
|
||||
|
||||
! Scale dialog
|
||||
ScaleDialog.lbl.scaleRocket = Entire rocket
|
||||
|
@ -392,4 +392,7 @@ public abstract class Warning {
|
||||
public static final Warning ZERO_LENGTH_BODY = new Other(trans.get("Warning.ZERO_LENGTH_BODY"));
|
||||
public static final Warning ZERO_RADIUS_BODY = new Other(trans.get("Warning.ZERO_RADIUS_BODY"));
|
||||
|
||||
public static final Warning TUBE_STABILITY = new Other(trans.get("Warning.TUBE_STABILITY"));
|
||||
public static final Warning TUBE_SEPARATION = new Other(trans.get("Warning.TUBE_SEPARATION"));
|
||||
public static final Warning TUBE_OVERLAP = new Other(trans.get("Warning.TUBE_OVERLAP"));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
public class LaunchLugCalc extends RocketComponentCalc {
|
||||
public class LaunchLugCalc extends TubeCalc {
|
||||
|
||||
private final double CDmul;
|
||||
private final double refArea;
|
||||
|
@ -0,0 +1,27 @@
|
||||
package net.sf.openrocket.aerodynamics.barrowman;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.AerodynamicForces;
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
public abstract class TubeCalc extends RocketComponentCalc {
|
||||
|
||||
private final double CDmul;
|
||||
protected final double refArea;
|
||||
|
||||
public TubeCalc(RocketComponent component) {
|
||||
super(component);
|
||||
|
||||
LaunchLug lug = (LaunchLug)component;
|
||||
double ld = lug.getLength() / (2*lug.getOuterRadius());
|
||||
|
||||
CDmul = Math.max(1.3 - ld, 1);
|
||||
refArea = Math.PI * MathUtil.pow2(lug.getOuterRadius()) -
|
||||
Math.PI * MathUtil.pow2(lug.getInnerRadius()) * Math.max(1 - ld, 0);
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,7 @@ import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.aerodynamics.Warning;
|
||||
import net.sf.openrocket.aerodynamics.Warning.Other;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
||||
@ -33,9 +34,9 @@ import org.slf4j.LoggerFactory;
|
||||
* @author kruland
|
||||
*
|
||||
*/
|
||||
public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
public class TubeFinSetCalc extends TubeCalc {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(FinSetCalc.class);
|
||||
private final static Logger log = LoggerFactory.getLogger(FinSetCalc.class);
|
||||
|
||||
private static final double STALL_ANGLE = (20 * Math.PI / 180);
|
||||
|
||||
@ -57,8 +58,13 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
protected double[] chordTrail = new double[DIVISIONS];
|
||||
protected double[] chordLength = new double[DIVISIONS];
|
||||
|
||||
protected final WarningSet geometryWarnings = new WarningSet();
|
||||
|
||||
private final double[] poly = new double[6];
|
||||
|
||||
private final double wettedArea;
|
||||
private final double frontalArea;
|
||||
|
||||
private final double thickness;
|
||||
private final double bodyRadius;
|
||||
private final int finCount;
|
||||
@ -73,9 +79,52 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
throw new IllegalArgumentException("Illegal component type " + component);
|
||||
}
|
||||
|
||||
TubeFinSet fin = (TubeFinSet) component;
|
||||
final TubeFinSet tubes = (TubeFinSet) component;
|
||||
final TubeFinSet fin = tubes; // keep this around while we're still leveraging FinSet
|
||||
|
||||
geometryWarnings.add(Warning.TUBE_STABILITY);
|
||||
if (tubes.getTubeSeparation() > MathUtil.EPSILON) {
|
||||
geometryWarnings.add(Warning.TUBE_SEPARATION);
|
||||
} else if (tubes.getTubeSeparation() < -MathUtil.EPSILON) {
|
||||
geometryWarnings.add(Warning.TUBE_OVERLAP);
|
||||
}
|
||||
|
||||
// precompute geometry
|
||||
bodyRadius = tubes.getBodyRadius();
|
||||
|
||||
// wetted area for friction drag calculation
|
||||
// Area of inner surface of tubes.
|
||||
final double innerArea = tubes.getFinCount() * tubes.getLength() * 2.0 * Math.PI * tubes.getInnerRadius();
|
||||
|
||||
// Area of the outer surface of tubes. Since roughly half
|
||||
// of the area is "masked" by the interstices between the tubes and the
|
||||
// body tube, only consider half the area
|
||||
final double outerArea = tubes.getFinCount() * tubes.getLength() * Math.PI * tubes.getOuterRadius();
|
||||
|
||||
// Area of the portion of the body tube masked by the tube fins
|
||||
final BodyTube parent = (BodyTube) tubes.getParent();
|
||||
final double maskedArea = tubes.getLength() * 2.0 * Math.PI * parent.getOuterRadius();
|
||||
|
||||
wettedArea = innerArea + outerArea - maskedArea;
|
||||
log.debug("wetted area of tube fins " + wettedArea);
|
||||
|
||||
// effective frontal area for pressure drag calculation
|
||||
// model interstices between tube fins and body tube as closed blunt area
|
||||
|
||||
// area of disk passing through tube fin centers
|
||||
final double tubeDiskArea = Math.PI * MathUtil.pow2(bodyRadius + tubes.getOuterRadius());
|
||||
|
||||
// half of combined area of tube fin interiors.
|
||||
final double tubeInnerArea = tubes.getFinCount() * Math.PI * MathUtil.pow2(tubes.getInnerRadius()) / 2.0;
|
||||
|
||||
// body tube area
|
||||
final double bodyTubeArea = Math.PI * MathUtil.pow2(bodyRadius);
|
||||
|
||||
// refArea is effective frontal area of a tube, from LaunchLugCalc
|
||||
frontalArea = tubes.getFinCount() * refArea + tubeDiskArea - tubeInnerArea - bodyTubeArea;
|
||||
log.debug("effective frontal area " + frontalArea);
|
||||
|
||||
thickness = fin.getThickness();
|
||||
bodyRadius = fin.getBodyRadius();
|
||||
finCount = 3 * fin.getFinCount();
|
||||
baseRotation = fin.getBaseRotation();
|
||||
cantAngle = 0;
|
||||
@ -113,14 +162,13 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
if( (0 < bodyRadius) && (thickness > bodyRadius / 2)){
|
||||
warnings.add(Warning.THICK_FIN);
|
||||
}
|
||||
warnings.add(new Other("Tube fin support is experimental"));
|
||||
|
||||
//////// Calculate CNa. /////////
|
||||
|
||||
// One fin without interference (both sub- and supersonic):
|
||||
double cna1 = calculateFinCNa1(conditions);
|
||||
|
||||
// logger.debug("Component cna1 = {}", cna1);
|
||||
// log.debug("Component cna1 = {}", cna1);
|
||||
|
||||
// Multiple fins with fin-fin interference
|
||||
double cna;
|
||||
@ -141,7 +189,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
cna = cna1 * finCount / 2.0;
|
||||
}
|
||||
|
||||
// logger.debug("Component cna = {}", cna);
|
||||
// log.debug("Component cna = {}", cna);
|
||||
|
||||
// Take into account fin-fin interference effects
|
||||
switch (interferenceFinCount) {
|
||||
@ -182,7 +230,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
tau = 0;
|
||||
cna *= 1 + tau; // Classical Barrowman
|
||||
// cna *= pow2(1 + tau); // Barrowman thesis (too optimistic??)
|
||||
// logger.debug("Component cna = {}", cna);
|
||||
// log.debug("Component cna = {}", cna);
|
||||
|
||||
// TODO: LOW: check for fin tip mach cone interference
|
||||
// (Barrowman thesis pdf-page 40)
|
||||
@ -191,9 +239,9 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
|
||||
// Calculate CP position
|
||||
double x = macLead + calculateCPPos(conditions) * macLength;
|
||||
// logger.debug("Component macLead = {}", macLead);
|
||||
// logger.debug("Component macLength = {}", macLength);
|
||||
// logger.debug("Component x = {}", x);
|
||||
// log.debug("Component macLead = {}", macLead);
|
||||
// log.debug("Component macLength = {}", macLength);
|
||||
// log.debug("Component x = {}", x);
|
||||
|
||||
|
||||
// Calculate roll forces, reduce forcing above stall angle
|
||||
@ -352,7 +400,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
double y = i * dy;
|
||||
|
||||
macLength += length * length;
|
||||
logger.debug("macLength = {}, length = {}, i = {}", macLength, length, i);
|
||||
log.debug("macLength = {}, length = {}, i = {}", macLength, length, i);
|
||||
macSpan += y * length;
|
||||
macLead += chordLead[i] * length;
|
||||
area += length;
|
||||
@ -368,7 +416,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
}
|
||||
|
||||
macLength *= dy;
|
||||
logger.debug("macLength = {}", macLength);
|
||||
log.debug("macLength = {}", macLength);
|
||||
macSpan *= dy;
|
||||
macLead *= dy;
|
||||
area *= dy;
|
||||
@ -537,7 +585,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
*/
|
||||
private double calculateCPPos(FlightConditions cond) {
|
||||
double m = cond.getMach();
|
||||
// logger.debug("m = {} ", m);
|
||||
// log.debug("m = {} ", m);
|
||||
if (m <= 0.5) {
|
||||
// At subsonic speeds CP at quarter chord
|
||||
return 0.25;
|
||||
@ -556,7 +604,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
val += poly[i] * x;
|
||||
x *= m;
|
||||
}
|
||||
// logger.debug("val = {}", val);
|
||||
// log.debug("val = {}", val);
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -587,79 +635,23 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
poly[0] = (9.16049 * (-0.588838 + ar) * (-0.20624 + ar)) / denom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warnings) {
|
||||
warnings.addAll(geometryWarnings);
|
||||
|
||||
// @SuppressWarnings("null")
|
||||
// public static void main(String arg[]) {
|
||||
// Rocket rocket = TestRocket.makeRocket();
|
||||
// FinSet finset = null;
|
||||
//
|
||||
// Iterator<RocketComponent> iter = rocket.deepIterator();
|
||||
// while (iter.hasNext()) {
|
||||
// RocketComponent c = iter.next();
|
||||
// if (c instanceof FinSet) {
|
||||
// finset = (FinSet)c;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// ((TrapezoidFinSet)finset).setHeight(0.10);
|
||||
// ((TrapezoidFinSet)finset).setRootChord(0.10);
|
||||
// ((TrapezoidFinSet)finset).setTipChord(0.10);
|
||||
// ((TrapezoidFinSet)finset).setSweep(0.0);
|
||||
//
|
||||
//
|
||||
// FinSetCalc calc = new FinSetCalc(finset);
|
||||
//
|
||||
// calc.calculateFinGeometry();
|
||||
// FlightConditions cond = new FlightConditions(new Configuration(rocket));
|
||||
// for (double m=0; m < 3; m+=0.05) {
|
||||
// cond.setMach(m);
|
||||
// cond.setAOA(0.0*Math.PI/180);
|
||||
// double cna = calc.calculateFinCNa1(cond);
|
||||
// System.out.printf("%5.2f "+cna+"\n", m);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
final double frictionCD = componentCf * wettedArea / conditions.getRefArea();
|
||||
log.debug("frictionCD " + frictionCD);
|
||||
return frictionCD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculatePressureCD(FlightConditions conditions,
|
||||
double stagnationCD, double baseCD, WarningSet warnings) {
|
||||
|
||||
double mach = conditions.getMach();
|
||||
double cd = 0;
|
||||
warnings.addAll(geometryWarnings);
|
||||
|
||||
// Pressure fore-drag
|
||||
if (crossSection == FinSet.CrossSection.AIRFOIL ||
|
||||
crossSection == FinSet.CrossSection.ROUNDED) {
|
||||
|
||||
// Round leading edge
|
||||
if (mach < 0.9) {
|
||||
cd = Math.pow(1 - pow2(mach), -0.417) - 1;
|
||||
} else if (mach < 1) {
|
||||
cd = 1 - 1.785 * (mach - 0.9);
|
||||
} else {
|
||||
cd = 1.214 - 0.502 / pow2(mach) + 0.1095 / pow2(pow2(mach));
|
||||
}
|
||||
|
||||
} else if (crossSection == FinSet.CrossSection.SQUARE) {
|
||||
cd = stagnationCD;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unsupported fin profile: " + crossSection);
|
||||
}
|
||||
|
||||
// Slanted leading edge
|
||||
cd *= pow2(cosGammaLead);
|
||||
|
||||
// Trailing edge drag
|
||||
if (crossSection == FinSet.CrossSection.SQUARE) {
|
||||
cd += baseCD;
|
||||
} else if (crossSection == FinSet.CrossSection.ROUNDED) {
|
||||
cd += baseCD / 2;
|
||||
}
|
||||
// Airfoil assumed to have zero base drag
|
||||
|
||||
// Scale to correct reference area
|
||||
cd *= finCount * span * thickness / conditions.getRefArea();
|
||||
final double cd = (stagnationCD + baseCD) * frontalArea / conditions.getRefArea();
|
||||
log.debug("pressure CD " + cd);
|
||||
|
||||
return cd;
|
||||
}
|
||||
@ -672,11 +664,4 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
||||
|
||||
return 3 * component.getFinCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warnings) {
|
||||
// launch lug doesn't add enough area to worry about
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user