[fix] Fixes the way BarrowmanCalculator handles instancing, particularly for ComponentAssemblies
This commit is contained in:
parent
e6b788cb0b
commit
fab167abdc
@ -286,7 +286,7 @@ public class AerodynamicForces implements Cloneable, Monitorable {
|
|||||||
/**
|
/**
|
||||||
* Zero all values to 0 / Coordinate.NUL. Component is left as it was.
|
* Zero all values to 0 / Coordinate.NUL. Component is left as it was.
|
||||||
*/
|
*/
|
||||||
public void zero() {
|
public AerodynamicForces zero() {
|
||||||
// component untouched
|
// component untouched
|
||||||
|
|
||||||
setAxisymmetric(true);
|
setAxisymmetric(true);
|
||||||
@ -303,6 +303,8 @@ public class AerodynamicForces implements Cloneable, Monitorable {
|
|||||||
setCD(0);
|
setCD(0);
|
||||||
setPitchDampingMoment(0);
|
setPitchDampingMoment(0);
|
||||||
setYawDampingMoment(0);
|
setYawDampingMoment(0);
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -388,4 +390,39 @@ public class AerodynamicForces implements Cloneable, Monitorable {
|
|||||||
public int getModID() {
|
public int getModID() {
|
||||||
return modID;
|
return modID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AerodynamicForces merge(AerodynamicForces other) {
|
||||||
|
|
||||||
|
this.cp = cp.average(other.getCP());
|
||||||
|
this.CNa = CNa + other.getCNa();
|
||||||
|
this.CN = CN + other.getCN();
|
||||||
|
this.Cm = Cm + other.getCm();
|
||||||
|
this.Cside = Cside + other.getCside();
|
||||||
|
this.Cyaw = Cyaw + other.getCyaw();
|
||||||
|
this.Croll = Croll + other.getCroll();
|
||||||
|
this.CrollDamp = CrollDamp + other.getCrollDamp();
|
||||||
|
this.CrollForce = CrollForce + other.getCrollForce();
|
||||||
|
|
||||||
|
modID++;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AerodynamicForces multiplex(final int instanceCount) {
|
||||||
|
|
||||||
|
this.cp = cp.setWeight(cp.weight*instanceCount);
|
||||||
|
this.CNa = CNa*instanceCount;
|
||||||
|
this.CN = CN*instanceCount;
|
||||||
|
this.Cm = Cm*instanceCount;
|
||||||
|
this.Cside = Cside*instanceCount;
|
||||||
|
this.Cyaw = Cyaw*instanceCount;
|
||||||
|
this.Croll = Croll*instanceCount;
|
||||||
|
this.CrollDamp = CrollDamp*instanceCount;
|
||||||
|
this.CrollForce = CrollForce*instanceCount;
|
||||||
|
|
||||||
|
modID++;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -158,22 +158,16 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
* Perform the actual CP calculation.
|
* Perform the actual CP calculation.
|
||||||
*/
|
*/
|
||||||
private AerodynamicForces calculateNonAxialForces(FlightConfiguration configuration, FlightConditions conditions,
|
private AerodynamicForces calculateNonAxialForces(FlightConfiguration configuration, FlightConditions conditions,
|
||||||
Map<RocketComponent, AerodynamicForces> map, WarningSet warnings) {
|
Map<RocketComponent, AerodynamicForces> calculators, WarningSet warnings) {
|
||||||
|
|
||||||
checkCache(configuration);
|
checkCache(configuration);
|
||||||
|
|
||||||
AerodynamicForces total = new AerodynamicForces();
|
|
||||||
total.zero();
|
|
||||||
|
|
||||||
AerodynamicForces forces = new AerodynamicForces();
|
|
||||||
|
|
||||||
if (warnings == null)
|
if (warnings == null)
|
||||||
warnings = ignoreWarningSet;
|
warnings = ignoreWarningSet;
|
||||||
|
|
||||||
if (conditions.getAOA() > 17.5 * Math.PI / 180)
|
if (conditions.getAOA() > 17.5 * Math.PI / 180)
|
||||||
warnings.add(new Warning.LargeAOA(conditions.getAOA()));
|
warnings.add(new Warning.LargeAOA(conditions.getAOA()));
|
||||||
|
|
||||||
|
|
||||||
if (calcMap == null)
|
if (calcMap == null)
|
||||||
buildCalcMap(configuration);
|
buildCalcMap(configuration);
|
||||||
|
|
||||||
@ -182,60 +176,60 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
warnings.add( Warning.DIAMETER_DISCONTINUITY);
|
warnings.add( Warning.DIAMETER_DISCONTINUITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (RocketComponent component : configuration.getActiveComponents()) {
|
AerodynamicForces total = calculateAssemblyNonAxialForces(configuration.getRocket(), configuration, conditions, calculators, warnings, "");
|
||||||
|
|
||||||
// Skip non-aerodynamic components
|
|
||||||
if (!component.isAerodynamic())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
|
||||||
// Call calculation method
|
|
||||||
forces.zero();
|
|
||||||
RocketComponentCalc calcObj = calcMap.get(component);
|
|
||||||
calcObj.calculateNonaxialForces(conditions, forces, warnings);
|
|
||||||
|
|
||||||
|
|
||||||
// previous unstable version
|
|
||||||
// int instanceCount = component.getLocations().length;
|
|
||||||
final boolean isAssembly = (component.allowsChildren() && (component.getInstanceCount() > 1));
|
|
||||||
|
|
||||||
// we will need to adjust the calculations *somehow* here...
|
|
||||||
|
|
||||||
Coordinate x_cp_comp = forces.getCP();
|
|
||||||
Coordinate x_cp_weighted = x_cp_comp.setWeight(x_cp_comp.weight);
|
|
||||||
Coordinate x_cp_absolute = component.toAbsolute(x_cp_weighted)[0];
|
|
||||||
forces.setCP(x_cp_absolute);
|
|
||||||
double CN_instanced = forces.getCN();
|
|
||||||
forces.setCm(CN_instanced * forces.getCP().x / conditions.getRefLength());
|
|
||||||
|
|
||||||
if (map != null) {
|
|
||||||
AerodynamicForces f = map.get(component);
|
|
||||||
|
|
||||||
f.setCP(forces.getCP());
|
|
||||||
f.setCNa(forces.getCNa());
|
|
||||||
f.setCN(forces.getCN());
|
|
||||||
f.setCm(forces.getCm());
|
|
||||||
f.setCside(forces.getCside());
|
|
||||||
f.setCyaw(forces.getCyaw());
|
|
||||||
f.setCroll(forces.getCroll());
|
|
||||||
f.setCrollDamp(forces.getCrollDamp());
|
|
||||||
f.setCrollForce(forces.getCrollForce());
|
|
||||||
}
|
|
||||||
|
|
||||||
total.setCP(total.getCP().average(forces.getCP()));
|
|
||||||
total.setCNa(total.getCNa() + forces.getCNa());
|
|
||||||
total.setCN(total.getCN() + forces.getCN());
|
|
||||||
total.setCm(total.getCm() + forces.getCm());
|
|
||||||
total.setCside(total.getCside() + forces.getCside());
|
|
||||||
total.setCyaw(total.getCyaw() + forces.getCyaw());
|
|
||||||
total.setCroll(total.getCroll() + forces.getCroll());
|
|
||||||
total.setCrollDamp(total.getCrollDamp() + forces.getCrollDamp());
|
|
||||||
total.setCrollForce(total.getCrollForce() + forces.getCrollForce());
|
|
||||||
}
|
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AerodynamicForces calculateAssemblyNonAxialForces( final RocketComponent component,
|
||||||
|
FlightConfiguration configuration, FlightConditions conditions,
|
||||||
|
Map<RocketComponent, AerodynamicForces> calculators, WarningSet warnings,
|
||||||
|
String indent) {
|
||||||
|
|
||||||
|
final AerodynamicForces assemblyForces= new AerodynamicForces().zero();
|
||||||
|
|
||||||
|
// System.err.println(String.format("%s@@ %s <%s>", indent, component.getName(), component.getClass().getSimpleName()));
|
||||||
|
|
||||||
|
// ==== calculate child forces ====
|
||||||
|
for (RocketComponent child: component.getChildren()) {
|
||||||
|
AerodynamicForces childForces = calculateAssemblyNonAxialForces( child, configuration, conditions, calculators, warnings, indent+" ");
|
||||||
|
assemblyForces.merge(childForces);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate *this* component's forces
|
||||||
|
RocketComponentCalc calcObj = calcMap.get(component);
|
||||||
|
if(null != calcObj) {
|
||||||
|
AerodynamicForces componentForces = new AerodynamicForces().zero();
|
||||||
|
calcObj.calculateNonaxialForces(conditions, componentForces, warnings);
|
||||||
|
|
||||||
|
Coordinate x_cp_comp = componentForces.getCP();
|
||||||
|
Coordinate x_cp_weighted = x_cp_comp.setWeight(x_cp_comp.weight);
|
||||||
|
Coordinate x_cp_absolute = component.toAbsolute(x_cp_weighted)[0];
|
||||||
|
componentForces.setCP(x_cp_absolute);
|
||||||
|
double CN_instanced = componentForces.getCN();
|
||||||
|
componentForces.setCm(CN_instanced * componentForces.getCP().x / conditions.getRefLength());
|
||||||
|
|
||||||
|
// if( 0.0001 < Math.abs(0 - componentForces.getCNa())){
|
||||||
|
// System.err.println(String.format("%s....Component.CNa: %g @ CPx: %g", indent, componentForces.getCNa(), componentForces.getCP().x));
|
||||||
|
// }
|
||||||
|
|
||||||
|
assemblyForces.merge(componentForces);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if( 0.0001 < Math.abs(0 - assemblyForces.getCNa())){
|
||||||
|
// System.err.println(String.format("%s....Assembly.CNa: %g @ CPx: %g", indent, assemblyForces.getCNa(), assemblyForces.getCP().x));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fetches instanced versions
|
||||||
|
// int instanceCount = component.getLocations().length;
|
||||||
|
|
||||||
|
if( component.allowsChildren() && (component.getInstanceCount() > 1)) {
|
||||||
|
return assemblyForces.multiplex(component.getInstanceCount());
|
||||||
|
}else {
|
||||||
|
return assemblyForces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isContinuous( final Rocket rkt){
|
public boolean isContinuous( final Rocket rkt){
|
||||||
|
@ -108,7 +108,6 @@ public class BarrowmanCalculatorTest {
|
|||||||
assertEquals(" Estes Alpha III CNa value is incorrect:", exp_cna, calcCP.weight, EPSILON);
|
assertEquals(" Estes Alpha III CNa value is incorrect:", exp_cna, calcCP.weight, EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCPDoubleStrapOn() {
|
public void testCPDoubleStrapOn() {
|
||||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||||
@ -117,8 +116,8 @@ public class BarrowmanCalculatorTest {
|
|||||||
FlightConditions conditions = new FlightConditions(config);
|
FlightConditions conditions = new FlightConditions(config);
|
||||||
WarningSet warnings = new WarningSet();
|
WarningSet warnings = new WarningSet();
|
||||||
|
|
||||||
double expCPx = 0.994642;
|
double expCPx = 1.04662388;
|
||||||
double expCNa = 15.437111;
|
double expCNa = 21.5111598;
|
||||||
Coordinate calcCP = calc.getCP(config, conditions, warnings);
|
Coordinate calcCP = calc.getCP(config, conditions, warnings);
|
||||||
|
|
||||||
assertEquals(" Falcon 9 Heavy CP x value is incorrect:", expCPx, calcCP.x, EPSILON);
|
assertEquals(" Falcon 9 Heavy CP x value is incorrect:", expCPx, calcCP.x, EPSILON);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user