Merge pull request #1280 from JoePfeiffer/refactor-friction-drag

Refactor friction drag
This commit is contained in:
SiboVG 2022-04-19 17:36:52 +02:00 committed by GitHub
commit 1fd4dffd6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 179 additions and 128 deletions

View File

@ -323,18 +323,138 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
* @return friction drag for entire rocket
*/
private double calculateFrictionCD(FlightConfiguration configuration, FlightConditions conditions,
Map<RocketComponent, AerodynamicForces> map, WarningSet set) {
double c1 = 1.0, c2 = 1.0;
Map<RocketComponent, AerodynamicForces> map, WarningSet warningSet) {
double mach = conditions.getMach();
double Re;
double Cf;
double Re = calculateReynoldsNumber(configuration, conditions);
double Cf = calculateFrictionCoefficient(configuration, mach, Re);
double roughnessCorrection = calculateRoughnessCorrection(mach);
if (calcMap == null)
buildCalcMap(configuration);
/*
* Calculate the friction drag coefficient.
*
* The body wetted area is summed up and finally corrected with the rocket
* fineness ratio (calculated in the same iteration). The fins are corrected
* for thickness as we go on.
*/
double finFrictionCD = 0;
double bodyFrictionCD = 0;
double maxR = 0, minX = Double.MAX_VALUE, maxX = 0;
double[] roughnessLimited = new double[Finish.values().length];
Arrays.fill(roughnessLimited, Double.NaN);
Re = conditions.getVelocity() * configuration.getLength() /
conditions.getAtmosphericConditions().getKinematicViscosity();
final InstanceMap imap = configuration.getActiveInstances();
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent c = entry.getKey();
if (!c.isAerodynamic())
continue;
// Handle Overriden CD for Whole Rocket
if(c.isCDOverridden()) {
continue;
}
// Calculate the roughness-limited friction coefficient
Finish finish = ((ExternalComponent) c).getFinish();
if (Double.isNaN(roughnessLimited[finish.ordinal()])) {
roughnessLimited[finish.ordinal()] =
0.032 * Math.pow(finish.getRoughnessSize() / configuration.getLength(), 0.2) *
roughnessCorrection;
}
/*
* Actual Cf is maximum of Cf and the roughness-limited value.
* For perfect finish require additionally that Re > 1e6
*/
double componentCf;
if (configuration.getRocket().isPerfectFinish()) {
// For perfect finish require Re > 1e6
if ((Re > 1.0e6) && (roughnessLimited[finish.ordinal()] > Cf)) {
componentCf = roughnessLimited[finish.ordinal()];
} else {
componentCf = Cf;
}
} else {
// For fully turbulent use simple max
componentCf = Math.max(Cf, roughnessLimited[finish.ordinal()]);
}
// iterate across component instances
final ArrayList<InstanceContext> contextList = entry.getValue();
for(InstanceContext context: contextList ) {
double componentFrictionCD = calcMap.get(c).calculateFrictionCD(conditions, componentCf, warningSet);
if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c;
bodyFrictionCD += componentFrictionCD;
final double componentMinX = context.getLocation().x;
minX = Math.min(minX, componentMinX);
final double componentMaxX = componentMinX + c.getLength();
maxX = Math.max(maxX, componentMaxX);
final double componentMaxR = Math.max(s.getForeRadius(), s.getAftRadius());
maxR = Math.max(maxR, componentMaxR);
} else if (c instanceof FinSet) {
finFrictionCD += componentFrictionCD;
}
if (map != null) {
map.get(c).setFrictionCD(componentFrictionCD);
}
}
}
// fB may be POSITIVE_INFINITY, but that's ok for us
double fB = (maxX - minX + 0.0001) / maxR;
double correction = (1 + 1.0 / (2 * fB));
// Correct body data in map
if (map != null) {
for (RocketComponent c : map.keySet()) {
if (c instanceof SymmetricComponent) {
map.get(c).setFrictionCD(map.get(c).getFrictionCD() * correction);
}
}
}
return finFrictionCD + correction * bodyFrictionCD;
}
/**
* Calculation of Reynolds Number
*
* @param configuration Rocket configuration
* @param conditions Flight conditions taken into account
* @return Reynolds Number
*/
private double calculateReynoldsNumber(FlightConfiguration configuration, FlightConditions conditions) {
return conditions.getVelocity() * configuration.getLength() /
conditions.getAtmosphericConditions().getKinematicViscosity();
}
/**
* Calculation of skin friction coefficient
*
*
* return skin friction coefficient
*/
private double calculateFrictionCoefficient(FlightConfiguration configuration, double mach, double Re) {
double Cf;
double c1 = 1.0, c2 = 1.0;
// Calculate the skin friction coefficient (assume non-roughness limited)
if (configuration.getRocket().isPerfectFinish()) {
@ -412,6 +532,19 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
}
}
return Cf;
}
/**
* Calculation of correction for roughness
*
* @param mach
* @return roughness correction
**/
private double calculateRoughnessCorrection(double mach) {
double c1, c2;
// Roughness-limited value correction term
double roughnessCorrection;
@ -424,126 +557,10 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
c2 = 1.0 / (1 + 0.18 * pow2(1.1));
roughnessCorrection = c2 * (mach - 0.9) / 0.2 + c1 * (1.1 - mach) / 0.2;
}
/*
* Calculate the friction drag coefficient.
*
* The body wetted area is summed up and finally corrected with the rocket
* fineness ratio (calculated in the same iteration). The fins are corrected
* for thickness as we go on.
*/
double finFriction = 0;
double bodyFriction = 0;
double maxR = 0, minX = Double.MAX_VALUE, maxX = 0;
double[] roughnessLimited = new double[Finish.values().length];
Arrays.fill(roughnessLimited, Double.NaN);
final InstanceMap imap = configuration.getActiveInstances();
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent c = entry.getKey();
// Consider only SymmetricComponents and FinSets:
if (!(c instanceof SymmetricComponent) &&
!(c instanceof FinSet))
continue;
// iterate across component instances
final ArrayList<InstanceContext> contextList = entry.getValue();
for(InstanceContext context: contextList ) {
// Calculate the roughness-limited friction coefficient
Finish finish = ((ExternalComponent) c).getFinish();
if (Double.isNaN(roughnessLimited[finish.ordinal()])) {
roughnessLimited[finish.ordinal()] =
0.032 * Math.pow(finish.getRoughnessSize() / configuration.getLength(), 0.2) *
roughnessCorrection;
}
/*
* Actual Cf is maximum of Cf and the roughness-limited value.
* For perfect finish require additionally that Re > 1e6
*/
double componentCf;
if (configuration.getRocket().isPerfectFinish()) {
// For perfect finish require Re > 1e6
if ((Re > 1.0e6) && (roughnessLimited[finish.ordinal()] > Cf)) {
componentCf = roughnessLimited[finish.ordinal()];
} else {
componentCf = Cf;
}
} else {
// For fully turbulent use simple max
componentCf = Math.max(Cf, roughnessLimited[finish.ordinal()]);
}
//Handle Overriden CD for Whole Rocket
if(c.isCDOverridden()) {
continue;
}
// Calculate the friction drag:
if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c;
bodyFriction += componentCf * s.getComponentWetArea();
if (map != null) {
// Corrected later
map.get(c).setFrictionCD(componentCf * s.getComponentWetArea()
/ conditions.getRefArea());
}
final double componentMinX = context.getLocation().x;
minX = Math.min(minX, componentMinX);
final double componentMaxX = componentMinX + c.getLength();
maxX = Math.max(maxX, componentMaxX);
final double componentMaxR = Math.max(s.getForeRadius(), s.getAftRadius());
maxR = Math.max(maxR, componentMaxR);
} else if (c instanceof FinSet) {
FinSet f = (FinSet) c;
double mac = ((FinSetCalc) calcMap.get(c)).getMACLength();
double cd = componentCf * (1 + 2 * f.getThickness() / mac) *
2 * f.getPlanformArea();
finFriction += cd;
if (map != null) {
map.get(c).setFrictionCD(cd / conditions.getRefArea());
}
}
}
}
// fB may be POSITIVE_INFINITY, but that's ok for us
double fB = (maxX - minX + 0.0001) / maxR;
double correction = (1 + 1.0 / (2 * fB));
// Correct body data in map
if (map != null) {
for (RocketComponent c : map.keySet()) {
if (c instanceof SymmetricComponent) {
map.get(c).setFrictionCD(map.get(c).getFrictionCD() * correction);
}
}
}
return (finFriction + correction * bodyFriction) / conditions.getRefArea();
return roughnessCorrection;
}
/**
* Calculation of drag coefficient due to pressure
*
@ -568,6 +585,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
final InstanceMap imap = configuration.getActiveInstances();
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent c = entry.getKey();
if (!c.isAerodynamic())
continue;
@ -579,7 +597,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
double cd = calcMap.get(c).calculatePressureCD(conditions, stagnation, base,
warningSet);
total += cd;
if (forceMap != null) {
forceMap.get(c).setPressureCD(cd);
}
@ -608,7 +626,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
}
}
}
return total;
}

View File

@ -621,6 +621,12 @@ public class FinSetCalc extends RocketComponentCalc {
// }
//
// }
@Override
public double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warnings) {
double cd = componentCf * (1 + 2 * thickness / macLength) * 2 * finArea / conditions.getRefArea();
return cd;
}
@Override
public double calculatePressureCD(FlightConditions conditions,

View File

@ -30,6 +30,12 @@ public class LaunchLugCalc extends RocketComponentCalc {
// Nothing to be done
}
@Override
public double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warnings) {
// launch lug doesn't add enough area to worry about
return 0;
}
@Override
public double calculatePressureCD(FlightConditions conditions,
double stagnationCD, double baseCD, WarningSet warnings) {

View File

@ -28,6 +28,16 @@ public abstract class RocketComponentCalc {
public abstract void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
AerodynamicForces forces, WarningSet warnings);
/**
* Calculates the friction drag of the component.
*
* @param conditions the flight conditions
* @param componentCF component coefficient of friction, calculated in BarrowmanCalculator
* @param warnings set in which to to store possible warnings
* @return the friction drag coefficient of the component
*/
public abstract double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warnings);
/**
* Calculates the pressure drag of the component. This component does NOT include
@ -37,7 +47,7 @@ public abstract class RocketComponentCalc {
* @param stagnationCD the current stagnation drag coefficient
* @param baseCD the current base drag coefficient
* @param warnings set in which to store possible warnings
* @return the pressure drag of the component
* @return the pressure drag coefficient of the component
*/
public abstract double calculatePressureCD(FlightConditions conditions,
double stagnationCD, double baseCD, WarningSet warnings);

View File

@ -45,6 +45,7 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
private final double frontalArea;
private final double fullVolume;
private final double planformArea, planformCenter;
private final double wetArea;
private final double sinphi;
public SymmetricComponentCalc(RocketComponent c) {
@ -53,7 +54,6 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
throw new IllegalArgumentException("Illegal component type " + c);
}
SymmetricComponent component = (SymmetricComponent) c;
length = component.getLength();
foreRadius = component.getForeRadius();
@ -63,6 +63,8 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
fullVolume = component.getFullVolume();
planformArea = component.getComponentPlanformArea();
planformCenter = component.getComponentPlanformCenter();
wetArea = component.getComponentWetArea();
if (component instanceof BodyTube) {
shape = null;
@ -174,7 +176,10 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
conditions.getSinAOA() * conditions.getSincAOA()); // sin(aoa)^2 / aoa
}
@Override
public double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warningSet) {
return componentCf * wetArea / conditions.getRefArea();
}
private LinearInterpolator interpolator = null;

View File

@ -672,5 +672,11 @@ 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;
}
}