forked from OpenMDAO/Aviary
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request OpenMDAO#317 from johnjasa/battery_integration
Adding simple battery subsystem and Dymos integration test
- Loading branch information
Showing
24 changed files
with
1,776 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1,112 changes: 1,112 additions & 0 deletions
1,112
aviary/models/engines/turbofan_28k_with_electric.deck
Large diffs are not rendered by default.
Oops, something went wrong.
158 changes: 158 additions & 0 deletions
158
aviary/models/test_aircraft/aircraft_for_bench_FwFm_with_electric.csv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
aircraft:air_conditioning:mass_scaler,1.0,unitless | ||
aircraft:anti_icing:mass_scaler,1.0,unitless | ||
aircraft:apu:mass_scaler,1.1,unitless | ||
aircraft:avionics:mass_scaler,1.2,unitless | ||
aircraft:canard:area,0.0,ft**2 | ||
aircraft:canard:aspect_ratio,0.0,unitless | ||
aircraft:canard:thickness_to_chord,0.0,unitless | ||
aircraft:crew_and_payload:baggage_mass_per_passenger,45.0,lbm | ||
aircraft:crew_and_payload:cargo_container_mass_scaler,1.0,unitless | ||
aircraft:crew_and_payload:flight_crew_mass_scaler,1.0,unitless | ||
aircraft:crew_and_payload:mass_per_passenger,180.0,lbm | ||
aircraft:crew_and_payload:misc_cargo,0.0,lbm | ||
aircraft:crew_and_payload:non_flight_crew_mass_scaler,1.0,unitless | ||
aircraft:crew_and_payload:num_business_class,0,unitless | ||
aircraft:crew_and_payload:num_first_class,11,unitless | ||
aircraft:crew_and_payload:num_flight_attendants,3,unitless | ||
aircraft:crew_and_payload:num_flight_crew,2,unitless | ||
aircraft:crew_and_payload:num_galley_crew,0,unitless | ||
aircraft:crew_and_payload:num_non_flight_crew,3,unitless | ||
aircraft:crew_and_payload:num_passengers,169,unitless | ||
aircraft:crew_and_payload:num_tourist_class,158,unitless | ||
aircraft:crew_and_payload:passenger_service_mass_scaler,1.0,unitless | ||
aircraft:crew_and_payload:wing_cargo,0.0,lbm | ||
aircraft:design:base_area,0.0,ft**2 | ||
aircraft:design:empty_mass_margin_scaler,0.0,unitless | ||
aircraft:design:lift_dependent_drag_coeff_factor,0.909839381134961,unitless | ||
aircraft:design:touchdown_mass,152800.0,lbm | ||
aircraft:design:reserve_fuel_additional,3000.,lbm | ||
aircraft:design:subsonic_drag_coeff_factor,1.0,unitless | ||
aircraft:design:supersonic_drag_coeff_factor,1.0,unitless | ||
aircraft:design:use_alt_mass,False,unitless | ||
aircraft:design:zero_lift_drag_coeff_factor,0.930890028006548,unitless | ||
aircraft:electrical:mass_scaler,1.25,unitless | ||
aircraft:engine:additional_mass_fraction,0.,unitless | ||
aircraft:engine:constant_fuel_consumption,0.,lbm/h | ||
aircraft:engine:data_file,models/engines/turbofan_28k_with_electric.deck,unitless | ||
aircraft:engine:flight_idle_thrust_fraction,0.0,unitless | ||
aircraft:engine:flight_idle_max_fraction,1.0,unitless | ||
aircraft:engine:flight_idle_min_fraction,0.08,unitless | ||
aircraft:engine:fuel_flow_scaler_constant_term,0.,unitless | ||
aircraft:engine:fuel_flow_scaler_linear_term,0.,unitless | ||
aircraft:engine:generate_flight_idle,True,unitless | ||
aircraft:engine:geopotential_alt,False,unitless | ||
aircraft:engine:ignore_negative_thrust,False,unitless | ||
aircraft:engine:interpolation_method,slinear,unitless | ||
aircraft:engine:mass_scaler,1.15,unitless | ||
aircraft:engine:mass,7400,lbm | ||
aircraft:engine:num_engines,2,unitless | ||
aircraft:engine:num_fuselage_engines,0,unitless | ||
aircraft:engine:num_wing_engines,2,unitless | ||
aircraft:engine:reference_mass,7400,lbm | ||
aircraft:engine:reference_sls_thrust,28928.1,lbf | ||
aircraft:engine:scale_mass,True,unitless | ||
aircraft:engine:scale_performance,True,unitless | ||
aircraft:engine:scaled_sls_thrust,28928.1,lbf | ||
aircraft:engine:subsonic_fuel_flow_scaler,1.,unitless | ||
aircraft:engine:supersonic_fuel_flow_scaler,1.,unitless | ||
aircraft:engine:thrust_reversers_mass_scaler,0.0,unitless | ||
aircraft:engine:wing_locations,[0.26869218],unitless | ||
aircraft:fins:area,0.0,ft**2 | ||
aircraft:fins:mass_scaler,1.0,unitless | ||
aircraft:fins:mass,0.0,lbm | ||
aircraft:fins:num_fins,0,unitless | ||
aircraft:fins:taper_ratio,10.0,unitless | ||
aircraft:fuel:auxiliary_fuel_capacity,0.0,lbm | ||
aircraft:fuel:density_ratio,1.0,unitless | ||
aircraft:fuel:fuel_system_mass_scaler,1.0,unitless | ||
aircraft:fuel:fuselage_fuel_capacity,0.0,lbm | ||
aircraft:fuel:num_tanks,7,unitless | ||
aircraft:fuel:total_capacity,45694.0,lbm | ||
aircraft:fuel:unusable_fuel_mass_scaler,1.0,unitless | ||
aircraft:furnishings:mass_scaler,1.1,unitless | ||
aircraft:fuselage:length,128.0,ft | ||
aircraft:fuselage:mass_scaler,1.05,unitless | ||
aircraft:fuselage:max_height,13.17,ft | ||
aircraft:fuselage:max_width,12.33,ft | ||
aircraft:fuselage:military_cargo_floor,False,unitless | ||
aircraft:fuselage:num_fuselages,1,unitless | ||
aircraft:fuselage:passenger_compartment_length,85.5,ft | ||
aircraft:fuselage:planform_area,1578.24,ft**2 | ||
aircraft:fuselage:wetted_area_scaler,1.0,unitless | ||
aircraft:fuselage:wetted_area,4158.62,ft**2 | ||
aircraft:horizontal_tail:area,355.0,ft**2 | ||
aircraft:horizontal_tail:aspect_ratio,6.0,unitless | ||
aircraft:horizontal_tail:mass_scaler,1.2,unitless | ||
aircraft:horizontal_tail:taper_ratio,0.22,unitless | ||
aircraft:horizontal_tail:thickness_to_chord,0.125,unitless | ||
aircraft:horizontal_tail:vertical_tail_fraction,0.0,unitless | ||
aircraft:horizontal_tail:wetted_area_scaler,1.0,unitless | ||
aircraft:horizontal_tail:wetted_area,592.65,ft**2 | ||
aircraft:hydraulics:mass_scaler,1.0,unitless | ||
aircraft:hydraulics:system_pressure,3000.0,lbf/ft**2 | ||
aircraft:instruments:mass_scaler,1.25,unitless | ||
aircraft:landing_gear:carrier_based,False,unitless | ||
aircraft:landing_gear:main_gear_mass_scaler,1.1,unitless | ||
aircraft:landing_gear:main_gear_oleo_length,102.0,inch | ||
aircraft:landing_gear:nose_gear_mass_scaler,1.0,unitless | ||
aircraft:landing_gear:nose_gear_oleo_length,67.0,inch | ||
aircraft:nacelle:avg_diameter,7.94,ft | ||
aircraft:nacelle:avg_length,12.3,ft | ||
aircraft:nacelle:count_factor,2,unitless | ||
aircraft:nacelle:mass_scaler,1.0,unitless | ||
aircraft:nacelle:wetted_area_scaler,1.0,unitless | ||
aircraft:paint:mass_per_unit_area,0.037,lbm/ft**2 | ||
aircraft:propulsion:engine_oil_mass_scaler,1.0,unitless | ||
aircraft:propulsion:misc_mass_scaler,1.0,unitless | ||
aircraft:vertical_tail:area,284.0,ft**2 | ||
aircraft:vertical_tail:aspect_ratio,1.75,unitless | ||
aircraft:vertical_tail:mass_scaler,1.0,unitless | ||
aircraft:vertical_tail:num_tails,1,unitless | ||
aircraft:vertical_tail:taper_ratio,0.33,unitless | ||
aircraft:vertical_tail:thickness_to_chord,0.1195,unitless | ||
aircraft:vertical_tail:wetted_area_scaler,1.0,unitless | ||
aircraft:vertical_tail:wetted_area,581.13,ft**2 | ||
aircraft:wing:aeroelastic_tailoring_factor,0.0,unitless | ||
aircraft:wing:airfoil_technology,1.92669766647637,unitless | ||
aircraft:wing:area,1370.0,ft**2 | ||
aircraft:wing:aspect_ratio,11.22091,unitless | ||
aircraft:wing:bending_mass_scaler,1.0,unitless | ||
aircraft:wing:chord_per_semispan,0.31,0.23,0.084,unitless | ||
aircraft:wing:composite_fraction,0.2,unitless | ||
aircraft:wing:control_surface_area,137,ft**2 | ||
aircraft:wing:control_surface_area_ratio,0.1,unitless | ||
aircraft:wing:glove_and_bat,134.0,ft**2 | ||
aircraft:wing:input_station_dist,0.,0.2759,0.9367,unitless | ||
aircraft:wing:load_distribution_control,2.0,unitless | ||
aircraft:wing:load_fraction,1.0,unitless | ||
aircraft:wing:load_path_sweep_dist,0.,22.,deg | ||
aircraft:wing:mass_scaler,1.23,unitless | ||
aircraft:wing:max_camber_at_70_semispan,0.0,unitless | ||
aircraft:wing:misc_mass_scaler,1.0,unitless | ||
aircraft:wing:num_integration_stations,50,unitless | ||
aircraft:wing:shear_control_mass_scaler,1.0,unitless | ||
aircraft:wing:span_efficiency_reduction,False,unitless | ||
aircraft:wing:span,117.83,ft | ||
aircraft:wing:strut_bracing_factor,0.0,unitless | ||
aircraft:wing:surface_ctrl_mass_scaler,1.0,unitless | ||
aircraft:wing:sweep,25.0,deg | ||
aircraft:wing:taper_ratio,0.278,unitless | ||
aircraft:wing:thickness_to_chord_dist,0.145,0.115,0.104,unitless | ||
aircraft:wing:thickness_to_chord,0.13,unitless | ||
aircraft:wing:ultimate_load_factor,3.75,unitless | ||
aircraft:wing:var_sweep_mass_penalty,0.0,unitless | ||
aircraft:wing:wetted_area_scaler,1.0,unitless | ||
aircraft:wing:wetted_area,2396.56,ft**2 | ||
mission:constraints:max_mach,0.785,unitless | ||
mission:design:cruise_altitude,35000,ft | ||
mission:design:gross_mass,175400.0,lbm | ||
mission:design:range,3500,NM | ||
mission:design:thrust_takeoff_per_eng,28928.1,lbf | ||
mission:landing:lift_coefficient_max,2.0,unitless | ||
mission:summary:cruise_mach,0.785,unitless | ||
mission:summary:fuel_flow_scaler,1.0,unitless | ||
mission:takeoff:fuel_simple,577,lbm | ||
mission:takeoff:lift_coefficient_max,3.0,unitless | ||
mission:takeoff:lift_over_drag,17.354,unitless | ||
settings:equations_of_motion,height_energy | ||
settings:mass_method,FLOPS |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import numpy as np | ||
import openmdao.api as om | ||
|
||
from aviary.subsystems.subsystem_builder_base import SubsystemBuilderBase | ||
from aviary.subsystems.energy.battery_sizing import SizeBattery | ||
from aviary.variable_info.variables import Aircraft, Dynamic | ||
|
||
|
||
class BatteryBuilder(SubsystemBuilderBase): | ||
default_name = 'battery' | ||
|
||
def build_pre_mission(self, aviary_inputs=None): | ||
return SizeBattery(aviary_inputs=aviary_inputs) | ||
|
||
def get_mass_names(self): | ||
return [Aircraft.Battery.MASS] | ||
|
||
def build_mission(self, num_nodes, aviary_inputs=None) -> om.Group: | ||
battery_group = om.Group() | ||
# Here, the efficiency variable is used as an overall efficiency for the battery | ||
soc = om.ExecComp('state_of_charge = (energy_capacity - (cumulative_electric_energy_used/efficiency)) / energy_capacity', | ||
state_of_charge={'val': np.zeros( | ||
num_nodes), 'units': 'unitless'}, | ||
energy_capacity={'val': 10.0, 'units': 'kJ'}, | ||
cumulative_electric_energy_used={ | ||
'val': np.zeros(num_nodes), 'units': 'kJ'}, | ||
efficiency={'val': 0.95, 'units': 'unitless'}) | ||
|
||
battery_group.add_subsystem('state_of_charge', | ||
subsys=soc, | ||
promotes_inputs=[('energy_capacity', Aircraft.Battery.ENERGY_CAPACITY), | ||
('cumulative_electric_energy_used', | ||
Dynamic.Mission.CUMULATIVE_ELECTRIC_ENERGY_USED), | ||
('efficiency', Aircraft.Battery.EFFICIENCY)], | ||
promotes_outputs=[('state_of_charge', Dynamic.Mission.BATTERY_STATE_OF_CHARGE)]) | ||
|
||
return battery_group | ||
|
||
def get_states(self): | ||
state_dict = {Dynamic.Mission.CUMULATIVE_ELECTRIC_ENERGY_USED: {'fix_initial': True, | ||
'fix_final': False, | ||
'lower': 0.0, | ||
'ref': 1e4, | ||
'defect_ref': 1e6, | ||
'units': 'kJ', | ||
'rate_source': Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, | ||
'input_initial': 0.0}} | ||
|
||
return state_dict | ||
|
||
def get_constraints(self): | ||
constraint_dict = { | ||
# Can add constraints here; state of charge is a common one in many battery applications | ||
f'battery.{Dynamic.Mission.BATTERY_STATE_OF_CHARGE}': | ||
{'type': 'boundary', | ||
'loc': 'final', | ||
'lower': 0.2}, | ||
} | ||
return constraint_dict |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import openmdao.api as om | ||
|
||
from aviary.utils.aviary_values import AviaryValues | ||
from aviary.variable_info.functions import add_aviary_input, add_aviary_output | ||
from aviary.variable_info.variables import Aircraft | ||
|
||
|
||
class SizeBattery(om.ExplicitComponent): | ||
''' | ||
Calculates battery mass from specific energy and additional mass | ||
''' | ||
|
||
def initialize(self): | ||
self.options.declare( | ||
'aviary_inputs', types=AviaryValues, | ||
desc='collection of Aircraft/Mission specific options') | ||
|
||
def setup(self): | ||
add_aviary_input(self, Aircraft.Battery.PACK_MASS, val=0.0, units='kg', | ||
desc='mass of energy-storing components of battery') | ||
add_aviary_input(self, Aircraft.Battery.ADDITIONAL_MASS, val=0.0, units='kg', | ||
desc='mass of non energy-storing components of battery') | ||
add_aviary_input(self, Aircraft.Battery.PACK_ENERGY_DENSITY, val=0.0, units='kJ/kg', | ||
desc='energy density of battery pack') | ||
|
||
add_aviary_output(self, Aircraft.Battery.MASS, val=0.0, | ||
units='kg', desc='total battery mass') | ||
add_aviary_output(self, Aircraft.Battery.ENERGY_CAPACITY, val=0.0, | ||
units='kJ', desc='total battery energy storage') | ||
|
||
def compute(self, inputs, outputs): | ||
energy_density_kj_kg = inputs[Aircraft.Battery.PACK_ENERGY_DENSITY] | ||
addtl_mass = inputs[Aircraft.Battery.ADDITIONAL_MASS] | ||
pack_mass = inputs[Aircraft.Battery.PACK_MASS] | ||
|
||
total_mass = pack_mass + addtl_mass | ||
total_energy = pack_mass * energy_density_kj_kg | ||
|
||
outputs[Aircraft.Battery.MASS] = total_mass | ||
outputs[Aircraft.Battery.ENERGY_CAPACITY] = total_energy | ||
|
||
def setup_partials(self): | ||
self.declare_partials(Aircraft.Battery.ENERGY_CAPACITY, | ||
Aircraft.Battery.PACK_ENERGY_DENSITY) | ||
self.declare_partials(Aircraft.Battery.ENERGY_CAPACITY, | ||
Aircraft.Battery.PACK_MASS) | ||
|
||
self.declare_partials(Aircraft.Battery.MASS, | ||
Aircraft.Battery.ADDITIONAL_MASS, val=1.0) | ||
self.declare_partials(Aircraft.Battery.MASS, | ||
Aircraft.Battery.PACK_MASS, val=1.0) | ||
|
||
def compute_partials(self, inputs, J): | ||
energy_density_kj_kg = inputs[Aircraft.Battery.PACK_ENERGY_DENSITY] | ||
pack_mass = inputs[Aircraft.Battery.PACK_MASS] | ||
|
||
J[Aircraft.Battery.ENERGY_CAPACITY, | ||
Aircraft.Battery.PACK_ENERGY_DENSITY] = pack_mass | ||
J[Aircraft.Battery.ENERGY_CAPACITY, | ||
Aircraft.Battery.PACK_MASS] = energy_density_kj_kg |
Empty file.
Oops, something went wrong.