Move tumble drag calculations into BasicTumbleStepper and eliminate BasicTumbleStatus
This commit is contained in:
parent
b6aaa3857a
commit
77d4bc890f
@ -1,85 +0,0 @@
|
|||||||
package net.sf.openrocket.simulation;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceMap;
|
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
|
||||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
|
||||||
|
|
||||||
public class BasicTumbleStatus extends SimulationStatus {
|
|
||||||
|
|
||||||
// Magic constants from techdoc.pdf
|
|
||||||
private final static double cDFin = 1.42;
|
|
||||||
private final static double cDBt = 0.56;
|
|
||||||
// Fin efficiency. Index is number of fins. The 0th entry is arbitrary and used to
|
|
||||||
// offset the indexes so finEff[1] is the coefficient for one fin from the table in techdoc.pdf
|
|
||||||
private final static double[] finEff = { 0.0, 0.5, 1.0, 1.41, 1.81, 1.73, 1.90, 1.85 };
|
|
||||||
|
|
||||||
private final double cd;
|
|
||||||
|
|
||||||
public BasicTumbleStatus(FlightConfiguration configuration,
|
|
||||||
SimulationConditions simulationConditions) {
|
|
||||||
super(configuration, simulationConditions);
|
|
||||||
this.cd = computeTumbleCD();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BasicTumbleStatus(SimulationStatus orig) {
|
|
||||||
super(orig);
|
|
||||||
if (orig instanceof BasicTumbleStatus) {
|
|
||||||
this.cd = ((BasicTumbleStatus) orig).cd;
|
|
||||||
} else {
|
|
||||||
this.cd = computeTumbleCD();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getCD() {
|
|
||||||
return cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private double computeTumbleCD() {
|
|
||||||
|
|
||||||
// Computed based on Sampo's experimentation as documented in the pdf.
|
|
||||||
|
|
||||||
// compute the fin and body tube projected areas
|
|
||||||
double aFins = 0.0;
|
|
||||||
double aBt = 0.0;
|
|
||||||
final InstanceMap imap = this.getConfiguration().getActiveInstances();
|
|
||||||
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
|
|
||||||
final RocketComponent component = entry.getKey();
|
|
||||||
|
|
||||||
if (!component.isAerodynamic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// iterate across component instances
|
|
||||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
|
||||||
for(InstanceContext context: contextList ) {
|
|
||||||
|
|
||||||
if (component instanceof FinSet) {
|
|
||||||
final FinSet finComponent = ((FinSet) component);
|
|
||||||
final double finArea = finComponent.getPlanformArea();
|
|
||||||
int finCount = finComponent.getFinCount();
|
|
||||||
|
|
||||||
// check bounds on finCount.
|
|
||||||
if (finCount >= finEff.length) {
|
|
||||||
finCount = finEff.length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
aFins += finArea * finEff[finCount] / finComponent.getFinCount();
|
|
||||||
|
|
||||||
} else if (component instanceof SymmetricComponent) {
|
|
||||||
aBt += ((SymmetricComponent) component).getComponentPlanformArea();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (cDFin * aFins + cDBt * aBt)/getConfiguration().getReferenceArea();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,16 @@
|
|||||||
package net.sf.openrocket.simulation;
|
package net.sf.openrocket.simulation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
|
import net.sf.openrocket.rocketcomponent.InstanceMap;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||||
|
|
||||||
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
|
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
|
||||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||||
@ -12,14 +23,66 @@ public class BasicTumbleStepper extends AbstractSimulationStepper {
|
|||||||
|
|
||||||
private static final double RECOVERY_TIME_STEP = 0.5;
|
private static final double RECOVERY_TIME_STEP = 0.5;
|
||||||
|
|
||||||
|
// Magic constants from techdoc.pdf
|
||||||
|
private final static double cDFin = 1.42;
|
||||||
|
private final static double cDBt = 0.56;
|
||||||
|
// Fin efficiency. Index is number of fins. The 0th entry is arbitrary and used to
|
||||||
|
// offset the indexes so finEff[1] is the coefficient for one fin from the table in techdoc.pdf
|
||||||
|
private final static double[] finEff = { 0.0, 0.5, 1.0, 1.41, 1.81, 1.73, 1.90, 1.85 };
|
||||||
|
|
||||||
|
private double cd;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SimulationStatus initialize(SimulationStatus original) {
|
public SimulationStatus initialize(SimulationStatus status) {
|
||||||
BasicTumbleStatus status = new BasicTumbleStatus(original);
|
this.cd = computeTumbleCD(status);
|
||||||
status.setWarnings(original.getWarnings());
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double getCD() {
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double computeTumbleCD(SimulationStatus status) {
|
||||||
|
|
||||||
|
// Computed based on Sampo's experimentation as documented in the pdf.
|
||||||
|
|
||||||
|
// compute the fin and body tube projected areas
|
||||||
|
double aFins = 0.0;
|
||||||
|
double aBt = 0.0;
|
||||||
|
final InstanceMap imap = status.getConfiguration().getActiveInstances();
|
||||||
|
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
|
||||||
|
final RocketComponent component = entry.getKey();
|
||||||
|
|
||||||
|
if (!component.isAerodynamic()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate across component instances
|
||||||
|
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||||
|
for(InstanceContext context: contextList ) {
|
||||||
|
|
||||||
|
if (component instanceof FinSet) {
|
||||||
|
final FinSet finComponent = ((FinSet) component);
|
||||||
|
final double finArea = finComponent.getPlanformArea();
|
||||||
|
int finCount = finComponent.getFinCount();
|
||||||
|
|
||||||
|
// check bounds on finCount.
|
||||||
|
if (finCount >= finEff.length) {
|
||||||
|
finCount = finEff.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aFins += finArea * finEff[finCount] / finComponent.getFinCount();
|
||||||
|
|
||||||
|
} else if (component instanceof SymmetricComponent) {
|
||||||
|
aBt += ((SymmetricComponent) component).getComponentPlanformArea();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (cDFin * aFins + cDBt * aBt)/status.getConfiguration().getReferenceArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void step(SimulationStatus status, double maxTimeStep) throws SimulationException {
|
public void step(SimulationStatus status, double maxTimeStep) throws SimulationException {
|
||||||
|
|
||||||
@ -33,7 +96,7 @@ public class BasicTumbleStepper extends AbstractSimulationStepper {
|
|||||||
// Get total CD
|
// Get total CD
|
||||||
double mach = airSpeed.length() / atmosphere.getMachSpeed();
|
double mach = airSpeed.length() / atmosphere.getMachSpeed();
|
||||||
|
|
||||||
double tumbleCD = ((BasicTumbleStatus)status).getCD();
|
double tumbleCD = getCD();
|
||||||
|
|
||||||
// Compute drag force
|
// Compute drag force
|
||||||
double dynP = (0.5 * atmosphere.getDensity() * airSpeed.length2());
|
double dynP = (0.5 * atmosphere.getDensity() * airSpeed.length2());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user