Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.jbgust.jsrm.infra.pressure.ChamberPressureCalculation Maven / Gradle / Ivy
package com.github.jbgust.jsrm.infra.pressure;
import com.github.jbgust.jsrm.application.JSRMConfig;
import com.github.jbgust.jsrm.application.motor.SolidRocketMotor;
import com.github.jbgust.jsrm.calculation.CalculatorBuilder;
import com.github.jbgust.jsrm.calculation.CalculatorResults;
import com.github.jbgust.jsrm.calculation.Formula;
import com.github.jbgust.jsrm.infra.ConstantsExtractor;
import com.github.jbgust.jsrm.infra.JSRMConstant;
import com.github.jbgust.jsrm.infra.pressure.resultprovider.BurningSurfaceResultProvider;
import com.github.jbgust.jsrm.infra.pressure.resultprovider.EndGrainSurfaceResultProvider;
import com.github.jbgust.jsrm.infra.pressure.resultprovider.GrainVolumeResultProvider;
import com.github.jbgust.jsrm.infra.pressure.resultprovider.ProgressionResultProvider;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static com.github.jbgust.jsrm.infra.pressure.ChamberPressureCalculation.Results.*;
import static com.github.jbgust.jsrm.infra.pressure.function.LowKnFunction.LOW_KN_MASS_STORAGE_RATE;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
public class ChamberPressureCalculation {
private SolidRocketMotor motor;
private JSRMConfig config;
private final Map constants;
private final Map initialValues;
public ChamberPressureCalculation(SolidRocketMotor motor, JSRMConfig config, Map constants) {
this.motor = motor;
this.config = config;
this.constants = constants;
initialValues = getInitialValues(motor, config);
}
public Map> compute() {
CalculatorResults pressureResults = computeChamberPressureDuringPropellantBurn();
CalculatorResults knResults = computeKn(pressureResults);
addNewConstantsFromPressureResults(pressureResults);
CalculatorResults postBurnPressureResults = computePostBurnPressure();
return buildResults(pressureResults, knResults, postBurnPressureResults);
}
private CalculatorResults computeKn(CalculatorResults pressureResults) {
return new CalculatorBuilder(PressureFormulas.KN)
.withResultsToSave(PressureFormulas.KN)
.withConstants(ConstantsExtractor.toCalculationFormat(constants))
.withResultLineProviders(
new BurningSurfaceResultProvider(motor.getPropellantGrain().getGrainConfigutation(), config.getNumberLineDuringBurnCalculation()),
new KnDependenciesResultsProvider(throatArea.name(), pressureResults.getResults(PressureFormulas.THROAT_AREA)))
.createCalculator()
.compute(0, config.getNumberLineDuringBurnCalculation());
}
private Map> buildResults(CalculatorResults pressureResults, CalculatorResults knResults, CalculatorResults postBurnPressureResults) {
int lastPressureResultsLine = config.getNumberLineDuringBurnCalculation() - 1;
List throatAreaResults = new ArrayList<>(pressureResults.getResults(PressureFormulas.THROAT_AREA));
IntStream.range(0, config.getNumberLineDuringPostBurnCalculation() + 1)
.forEach(value -> throatAreaResults.add(pressureResults.getResult(PressureFormulas.THROAT_AREA, lastPressureResultsLine)));
// During post burn pressure KN = 0 because burning surface = 0
List knResultValues = new ArrayList<>(knResults.getResults(PressureFormulas.KN));
IntStream.range(0, config.getNumberLineDuringPostBurnCalculation() + 1)
.forEach(value -> knResultValues.add(0d));
List massFlowRateValues = new ArrayList<>(pressureResults.getResults(PressureFormulas.NOZZLE_MASS_FLOW_RATE));
List grainMassValues = new ArrayList<>(pressureResults.getResults(PressureFormulas.GRAIN_MASS));
// linear decrease of MassFlow rate during post burn phase to 0 kg/s
double lastMassFlowRateComputed = massFlowRateValues.get(massFlowRateValues.size() - 1);
double massflowIncrement = lastMassFlowRateComputed/(config.getNumberLineDuringPostBurnCalculation()+1);
IntStream.range(0, config.getNumberLineDuringPostBurnCalculation() + 1)
.forEach(value -> massFlowRateValues.add(lastMassFlowRateComputed - (massflowIncrement * (value+1))));
// add 0g for grainMass during postBurn Result
IntStream.range(0, config.getNumberLineDuringPostBurnCalculation() + 1)
.forEach(value -> grainMassValues.add(0D));
List nozzlePassageAreaResults = new ArrayList<>(pressureResults.getResults(PressureFormulas.NOZZLE_CRITICAL_PASSAGE_AREA));
IntStream.range(0, config.getNumberLineDuringPostBurnCalculation() + 1)
.forEach(value -> nozzlePassageAreaResults.add(pressureResults.getResult(PressureFormulas.NOZZLE_CRITICAL_PASSAGE_AREA, lastPressureResultsLine)));
List timeSinceBurnStartResults = mergeResults(pressureResults, postBurnPressureResults, PressureFormulas.TIME_SINCE_BURN_STARTS, PostBurnPressureFormulas.POST_BURN_TIME_SINCE_BURN_STARTS);
List chamberPressureMPAResults = mergeResults(pressureResults, postBurnPressureResults, PressureFormulas.CHAMBER_PRESSURE_MPA, PostBurnPressureFormulas.POST_BURN_CHAMBER_PRESSURE_MPA);
List absoluteChamberPressureResults = mergeResults(pressureResults, postBurnPressureResults, PressureFormulas.ABSOLUTE_CHAMBER_PRESSURE, PostBurnPressureFormulas.POST_BURN_ABSOLUTE_CHAMBER_PRESSURE);
List absoluteChamberPressurePSIGResults = mergeResults(pressureResults, postBurnPressureResults, PressureFormulas.ABSOLUTE_CHAMBER_PRESSURE_PSIG, PostBurnPressureFormulas.POST_BURN_ABSOLUTE_CHAMBER_PRESSURE_PSIG);
//feed last line
timeSinceBurnStartResults.add(constants.get(JSRMConstant.tbinc) + timeSinceBurnStartResults.get(timeSinceBurnStartResults.size() - 1));
chamberPressureMPAResults.add(0d);
absoluteChamberPressureResults.add(0d);
absoluteChamberPressurePSIGResults.add(0d);
return ImmutableMap.>builder()
.put(throatArea, throatAreaResults)
.put(nozzleCriticalPassageArea, nozzlePassageAreaResults)
.put(timeSinceBurnStart, timeSinceBurnStartResults)
.put(chamberPressureMPA, chamberPressureMPAResults)
.put(absoluteChamberPressure, absoluteChamberPressureResults)
.put(absoluteChamberPressurePSIG, absoluteChamberPressurePSIGResults)
.put(kn, knResultValues)
.put(massFlowRate, massFlowRateValues)
.put(grainMass, grainMassValues)
.put(lowKNCorrection, singletonList(countLowKNFunctionUsage(pressureResults)))
.build();
}
private double countLowKNFunctionUsage(CalculatorResults pressureResults) {
if(constants.get(JSRMConstant.safeKN) == 1) {
return Long.valueOf(pressureResults.getResults(PressureFormulas.MASS_STORAGE_RATE).stream()
.filter(massStorageRate -> Double.compare(LOW_KN_MASS_STORAGE_RATE, massStorageRate) == 0)
.count()).doubleValue();
}
return 0d;
}
private List mergeResults(CalculatorResults pressureResults,
CalculatorResults postBurnPressureResults,
PressureFormulas pressureFormulas,
PostBurnPressureFormulas postBurnPressureFormulas) {
return Stream
.concat(
pressureResults.getResults(pressureFormulas).stream(),
postBurnPressureResults.getResults(postBurnPressureFormulas).stream())
.collect(toList());
}
private CalculatorResults computePostBurnPressure() {
initialValues.put(PostBurnPressureFormulas.POST_BURN_TIME_SINCE_BURN_STARTS, constants.get(JSRMConstant.tbout) + constants.get(JSRMConstant.tbinc));
return new CalculatorBuilder(PostBurnPressureFormulas.POST_BURN_ABSOLUTE_CHAMBER_PRESSURE_PSIG)
.withConstants(ConstantsExtractor.toCalculationFormat(constants))
.withInitialValues(initialValues)
.withResultsToSave(PostBurnPressureFormulas.values())
.createCalculator()
.compute(0, config.getNumberLineDuringPostBurnCalculation());
}
private CalculatorResults computeChamberPressureDuringPropellantBurn() {
return new CalculatorBuilder(PressureFormulas.ABSOLUTE_CHAMBER_PRESSURE_PSIG)
.withConstants(ConstantsExtractor.toCalculationFormat(constants))
.withInitialValues(initialValues)
.withResultsToSave(
PressureFormulas.THROAT_AREA,
PressureFormulas.NOZZLE_CRITICAL_PASSAGE_AREA,
PressureFormulas.TIME_SINCE_BURN_STARTS,
PressureFormulas.CHAMBER_PRESSURE_MPA,
PressureFormulas.ABSOLUTE_CHAMBER_PRESSURE,
PressureFormulas.ABSOLUTE_CHAMBER_PRESSURE_PSIG,
PressureFormulas.NOZZLE_MASS_FLOW_RATE,
PressureFormulas.GRAIN_MASS,
PressureFormulas.MASS_STORAGE_RATE
)
.withResultLineProviders(
new ProgressionResultProvider(config.getNumberLineDuringBurnCalculation()),
new EndGrainSurfaceResultProvider(motor.getPropellantGrain().getGrainConfigutation(), config.getNumberLineDuringBurnCalculation()),
new GrainVolumeResultProvider(motor.getPropellantGrain().getGrainConfigutation(), config.getNumberLineDuringBurnCalculation()))
.createCalculator()
.compute(JSRMConstant.START_CALCULATION_LINE, config.getNumberLineDuringBurnCalculation());
}
private void addNewConstantsFromPressureResults(CalculatorResults pressureResults) {
int lastPressureResultsLine = config.getNumberLineDuringBurnCalculation() - 1;
constants.put(JSRMConstant.tbout, pressureResults.getResult(PressureFormulas.TIME_SINCE_BURN_STARTS, lastPressureResultsLine));
constants.put(JSRMConstant.pbout, pressureResults.getResult(PressureFormulas.CHAMBER_PRESSURE_MPA, lastPressureResultsLine));
constants.put(JSRMConstant.astarf, pressureResults.getResult(PressureFormulas.NOZZLE_CRITICAL_PASSAGE_AREA, lastPressureResultsLine));
constants.put(JSRMConstant.expectedPfinal, 2 * constants.get(JSRMConstant.patm) + JSRMConstant.PMAXPERC / 100 * getPmax(pressureResults));
constants.put(JSRMConstant.tbinc, getTbinc(constants));
}
private double getPmax(CalculatorResults pressureResults) {
return pressureResults.getResults(PressureFormulas.ABSOLUTE_CHAMBER_PRESSURE).stream().max(Double::compareTo).get();
}
private Double getTbinc(Map constants) {
Map tbincVariables = Stream.of(JSRMConstant.vc, JSRMConstant.expectedPfinal, JSRMConstant.pbout, JSRMConstant.rat, JSRMConstant.to, JSRMConstant.astarf, JSRMConstant.cstar)
.collect(toMap(Enum::name, constants::get));
tbincVariables.put(IncrementTimeBurstSolver.NB_LINE_VARIABLE, (double) config.getNumberLineDuringPostBurnCalculation());
return new IncrementTimeBurstSolver().solve(tbincVariables);
}
private Map getInitialValues(SolidRocketMotor motor, JSRMConfig config) {
Map initialValues = new HashMap<>();
initialValues.put(PressureFormulas.TEMPORARY_CHAMBER_PRESSURE, config.getAmbiantPressureInMPa());
initialValues.put(PressureFormulas.TIME_SINCE_BURN_STARTS, 0d);
initialValues.put(PressureFormulas.MASS_GENERATION_RATE, 0d);
initialValues.put(PressureFormulas.NOZZLE_MASS_FLOW_RATE, 0d);
initialValues.put(PressureFormulas.MASS_STORAGE_RATE, 0d);
initialValues.put(PressureFormulas.MASS_COMBUSTION_PRODUCTS, 0d);
initialValues.put(PressureFormulas.DENSITY_COMBUSTION_PRODUCTS, 0d);
return initialValues;
}
public enum Results {
throatArea,
nozzleCriticalPassageArea,
timeSinceBurnStart,
chamberPressureMPA,
absoluteChamberPressure,
absoluteChamberPressurePSIG,
kn,
massFlowRate,
lowKNCorrection, grainMass;
}
}