Merge pull request #1068 from JoePfeiffer/fix-1063
Fix 1063 -- correct subsonic nose cone drag interpolation
This commit is contained in:
		
						commit
						06c02cdd1f
					
				@ -18,7 +18,8 @@ import net.sf.openrocket.util.MathUtil;
 | 
			
		||||
import net.sf.openrocket.util.PolyInterpolator;
 | 
			
		||||
import net.sf.openrocket.util.Transformation;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Calculates the aerodynamic properties of a <code>SymmetricComponent</code>.
 | 
			
		||||
@ -32,6 +33,8 @@ import net.sf.openrocket.util.Transformation;
 | 
			
		||||
 */
 | 
			
		||||
public class SymmetricComponentCalc extends RocketComponentCalc {
 | 
			
		||||
	
 | 
			
		||||
	private final static Logger log = LoggerFactory.getLogger(SymmetricComponentCalc.class);
 | 
			
		||||
	
 | 
			
		||||
	public static final double BODY_LIFT_K = 1.1;
 | 
			
		||||
	
 | 
			
		||||
	private final double length;
 | 
			
		||||
@ -375,7 +378,16 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
 | 
			
		||||
				interpolator.addPoint(m, stag * Math.pow(int1.getValue(m) / stag, log4));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		// dump transonic/supersonic knots, in a format easily imported into python
 | 
			
		||||
		String vel = "vel = [ ";
 | 
			
		||||
		String cd = "cd = [ ";
 | 
			
		||||
		for (double m : interpolator.getXPoints()) {
 | 
			
		||||
			vel = vel + m + ", ";
 | 
			
		||||
			cd = cd + interpolator.getValue(m) + ", ";
 | 
			
		||||
		}
 | 
			
		||||
		log.debug(vel + "]");
 | 
			
		||||
		log.debug(cd + "]");
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Now the transonic/supersonic region is ok.  We still need to interpolate
 | 
			
		||||
@ -391,6 +403,9 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
 | 
			
		||||
		
 | 
			
		||||
		double cdMach0 = 0.8 * pow2(sinphi);
 | 
			
		||||
		double minDeriv = (interpolator.getValue(min + 0.01) - minValue) / 0.01;
 | 
			
		||||
 | 
			
		||||
		log.debug("cdMach0 = " + cdMach0);
 | 
			
		||||
		log.debug("minDeriv = " + minDeriv);
 | 
			
		||||
		
 | 
			
		||||
		// These should not occur, but might cause havoc for the interpolation
 | 
			
		||||
		if ((cdMach0 >= minValue - 0.01) || (minDeriv <= 0.01)) {
 | 
			
		||||
@ -398,10 +413,10 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Cd = a*M^b + cdMach0
 | 
			
		||||
		double a = minValue - cdMach0;
 | 
			
		||||
		double b = minDeriv / a;
 | 
			
		||||
		final double b = min * minDeriv / (minValue - cdMach0);
 | 
			
		||||
		final double a = (minValue - cdMach0) / Math.pow(min, b);
 | 
			
		||||
		
 | 
			
		||||
		for (double m = 0; m < minValue; m += 0.05) {
 | 
			
		||||
		for (double m = 0; m < min; m += 0.05) {
 | 
			
		||||
			interpolator.addPoint(m, a * Math.pow(m, b) + cdMach0);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -103,4 +103,43 @@ public class SymmetricComponentCalcTest {
 | 
			
		||||
		assertEquals(" SymmetricComponentCalc produces bad C_m:  ", 0.0, forces.getCm(), EPSILON);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void testEllipseNoseconeDrag() {
 | 
			
		||||
	    Rocket rocket = TestRockets.makeEstesAlphaIII();
 | 
			
		||||
	    NoseCone nose = (NoseCone)rocket.getChild(0).getChild(0);
 | 
			
		||||
	    // use an ellipsoidal nose cone with fineness ratio 5
 | 
			
		||||
	    nose.setType(Transition.Shape.ELLIPSOID);
 | 
			
		||||
	    nose.setLength(nose.getAftRadius() * 5.0);
 | 
			
		||||
	    SymmetricComponentCalc calcObj = new SymmetricComponentCalc( nose );
 | 
			
		||||
	    
 | 
			
		||||
	    FlightConfiguration config = rocket.getSelectedConfiguration();
 | 
			
		||||
	    FlightConditions conditions = new FlightConditions(config);
 | 
			
		||||
	    conditions.setAOA(0.0);
 | 
			
		||||
 | 
			
		||||
	    WarningSet warnings = new WarningSet();
 | 
			
		||||
 | 
			
		||||
	    double frontalArea = Math.PI * nose.getAftRadius() * nose.getAftRadius();
 | 
			
		||||
		// vvv TEST vvv
 | 
			
		||||
	    // these values from a reimplementation of the pressure cd calculation in python
 | 
			
		||||
	    // values at M = 0, 0.05, ... , 1.15
 | 
			
		||||
		double cd[] = {
 | 
			
		||||
			8.000392024269301e-07, 2.422001414621988e-06, 2.0098855921838474e-05,
 | 
			
		||||
			8.295843903984836e-05, 0.000230425812213129, 0.0005104254351619708,
 | 
			
		||||
			0.0009783566607446353, 0.0016963974152150677, 0.0027329880483111142,
 | 
			
		||||
			0.004162427611715722, 0.006064546184601524, 0.008524431611715306,
 | 
			
		||||
			0.011632196831399358, 0.01548277847481293, 0.020175760185344116,
 | 
			
		||||
			0.02581521589534269, 0.032509569500239276, 0.04037146820686186,
 | 
			
		||||
			0.04951766743137877, 0.06006892556095394, 0.07214990722137526,
 | 
			
		||||
			0.08588909394291767, 0.10141870131021756, 0.11887460183385967 };
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < cd.length; i++) {
 | 
			
		||||
			double m = i/20.0;
 | 
			
		||||
			String buf = "SymmetricComponentCalc produces bad Cd at index " + i + "(m=" + m +")";
 | 
			
		||||
			conditions.setMach(m);
 | 
			
		||||
			double testcd = calcObj.calculatePressureDragForce(conditions, 0.0,  0.0, warnings) *
 | 
			
		||||
				conditions.getRefArea() / frontalArea;
 | 
			
		||||
			assertEquals(buf, cd[(int) Math.round(m*20)], testcd, EPSILON);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user