diff --git a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java index 63ede7ad9..97d7dd303 100644 --- a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java +++ b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java @@ -755,11 +755,17 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { final InstanceMap imap = configuration.getActiveInstances(); for(Map.Entry> entry: imap.entrySet() ) { final RocketComponent c = entry.getKey(); - + if (!(c instanceof SymmetricComponent)) { continue; } + + if (c.isCDOverridden() || + c.isCDOverriddenByAncestor()) { + continue; + } + SymmetricComponent s = (SymmetricComponent) c; double foreRadius = s.getForeRadius(); double aftRadius = s.getAftRadius(); @@ -770,35 +776,20 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { } int instanceCount = entry.getValue().size(); - - if (c.isCDOverridden() || - c.isCDOverriddenByAncestor()) { - continue; + + // get forward radius of next component + final SymmetricComponent nextComponent = s.getNextSymmetricComponent(); + double nextRadius; + if ((nextComponent != null) && configuration.isComponentActive(nextComponent)) { + nextRadius = nextComponent.getForeRadius(); + } else { + nextRadius = 0.0; } - - // if aft radius of previous component is greater than my forward radius, set - // its aft CD - double radius = 0; - final SymmetricComponent prevComponent = s.getPreviousSymmetricComponent(); - if (prevComponent != null && configuration.isComponentActive(prevComponent)) { - radius = prevComponent.getAftRadius(); - } - - if (radius > foreRadius) { - double area = Math.PI * (pow2(radius) - pow2(foreRadius)); - double cd = base * area / conditions.getRefArea(); - total += instanceCount * cd; - if ((forceMap != null) && (prevComponent != null)) { - forceMap.get(prevComponent).setBaseCD(cd); - } - } - - // if I'm the last component, set my base CD - // note: the iterator *should* serve up the next component.... buuuut .... - // this code is tested, and there's no compelling reason to change. - final SymmetricComponent n = s.getNextSymmetricComponent(); - if ((n == null) || !configuration.isStageActive(n.getStageNumber())) { - double area = Math.PI * pow2(aftRadius); + + // if fore radius of next component is less than my aft radius, set my + // base CD + if (nextRadius < aftRadius) { + double area = Math.PI * (pow2(aftRadius) - pow2(nextRadius)); double cd = base * area / conditions.getRefArea(); total += instanceCount * cd; if (forceMap != null) { diff --git a/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java b/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java index 3b1a66d20..ea423886c 100644 --- a/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java +++ b/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java @@ -499,6 +499,77 @@ public class BarrowmanCalculatorTest { assertEquals("should be warning from podset airframe overlap", 1, warnings.size()); } + @Test + public void testBaseDragWithOverride() { + final WarningSet warnings = new WarningSet(); + final BarrowmanCalculator calc = new BarrowmanCalculator(); + + // get base drag of minimal rocket consisting of just a tube. + final Rocket tubeRocket = new Rocket(); + final AxialStage tubeStage = new AxialStage(); + tubeRocket.addChild(tubeStage); + + final BodyTube tubeBodyTube = new BodyTube(); + tubeStage.addChild(tubeBodyTube); + + final FlightConfiguration tubeConfig = new FlightConfiguration(tubeRocket); + final FlightConditions tubeConditions = new FlightConditions(tubeConfig); + final AerodynamicForces tubeForces = calc.getAerodynamicForces(tubeConfig, tubeConditions, warnings); + final double tubeBaseCD = tubeForces.getBaseCD(); + + // get base CD of minimal rocket consisting of just a cone + final Rocket coneRocket = new Rocket(); + final AxialStage coneStage = new AxialStage(); + coneRocket.addChild(coneStage); + + NoseCone coneCone = new NoseCone(); + coneCone.setAftRadius(tubeBodyTube.getOuterRadius()); + coneStage.addChild(coneCone); + + final FlightConfiguration coneConfig = new FlightConfiguration(coneRocket); + final FlightConditions coneConditions = new FlightConditions(coneConfig); + final AerodynamicForces coneForces = calc.getAerodynamicForces(coneConfig, coneConditions, warnings); + final double coneBaseCD = coneForces.getBaseCD(); + + // now our test rocket, with a tube and a cone + final Rocket testRocket = new Rocket(); + final AxialStage testStage = new AxialStage(); + testRocket.addChild(testStage); + + final BodyTube testTube = new BodyTube(); + testTube.setOuterRadius(tubeBodyTube.getOuterRadius()); + testStage.addChild(testTube); + + final NoseCone testCone = new NoseCone(); + testCone.setAftRadius(coneCone.getAftRadius()); + testStage.addChild(testCone); + + FlightConfiguration testConfig = new FlightConfiguration(testRocket); + FlightConditions testConditions = new FlightConditions(testConfig); + + // no overrides + AerodynamicForces testForces = calc.getAerodynamicForces(testConfig, testConditions, warnings); + assertEquals("base CD should be base CD of tube plus base CD of cone", tubeBaseCD + coneBaseCD, testForces.getBaseCD(), EPSILON); + + // override tube CD + testTube.setCDOverridden(true); + testTube.setOverrideCD(0); + testForces = calc.getAerodynamicForces(testConfig, testConditions, warnings); + assertEquals("base CD should be base CD of cone", coneBaseCD, testForces.getBaseCD(), EPSILON); + + // override cone CD + testCone.setCDOverridden(true); + testCone.setOverrideCD(0); + testForces = calc.getAerodynamicForces(testConfig, testConditions, warnings); + assertEquals("base CD should be 0", 0.0, testForces.getBaseCD(), EPSILON); + + + // and turn off tube override + testTube.setCDOverridden(false); + testForces = calc.getAerodynamicForces(testConfig, testConditions, warnings); + assertEquals("base CD should be base CD of tube", tubeBaseCD, testForces.getBaseCD(), EPSILON); + } + /** * Tests railbutton drag. Really is testing instancing more than actual drag calculations, and making * sure we don't divide by 0 when not moving