Source code for fastga.models.propulsion.fuel_propulsion.basicTurbo_prop.openmdao

"""OpenMDAO wrapping of basic IC engine."""
#  This file is part of FAST-OAD_CS23 : A framework for rapid Overall Aircraft Design
#  Copyright (C) 2022  ONERA & ISAE-SUPAERO
#  FAST is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.

import numpy as np
from openmdao.core.component import Component

import fastoad.api as oad

from fastga.models.propulsion.fuel_propulsion.basicTurbo_prop.basicTP_engine import BasicTPEngine
from fastga.models.propulsion.propulsion import IPropulsion, BaseOMPropulsionComponent
from fastga.models.propulsion.fuel_propulsion.base import FuelEngineSet
from fastga.models.aerodynamics.external.propeller_code.compute_propeller_aero import (
    THRUST_PTS_NB,
    SPEED_PTS_NB,
)


[docs]@oad.RegisterPropulsion("fastga.wrapper.propulsion.basicTurboprop") class OMBasicTurbopropWrapper(oad.IOMPropulsionWrapper): """ Wrapper class of for basic IC engine model. It is made to allow a direct call to :class:`~.basicIC_engine.BasicICEngine` in an OpenMDAO component. Example of usage of this class:: import openmdao.api as om class MyComponent(om.ExplicitComponent): def initialize(): self._engine_wrapper = OMRubberEngineWrapper() def setup(): # Adds OpenMDAO variables that define the engine self._engine_wrapper.setup(self) # Do the normal setup self.add_input("my_input") [finish the setup...] def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): [do something] # Get the engine instance, with parameters defined from OpenMDAO inputs engine = self._engine_wrapper.get_model(inputs) # Run the engine model. This is a pure Python call. You have to define # its inputs before, and to use its outputs according to your needs sfc, thrust_rate, thrust = engine.compute_flight_points( mach, altitude, engine_setting, thrust_is_regulated, thrust_rate, thrust ) [do something else] ) """
[docs] def setup(self, component: Component): component.add_input("data:propulsion:turboprop:design_point:power", np.nan, units="kW") component.add_input( "data:propulsion:turboprop:design_point:turbine_entry_temperature", np.nan, units="K" ) component.add_input("data:propulsion:turboprop:design_point:OPR", np.nan) component.add_input("data:propulsion:turboprop:design_point:altitude", np.nan, units="m") component.add_input("data:propulsion:turboprop:design_point:mach", np.nan) component.add_input("data:propulsion:turboprop:off_design:bleed_usage", np.nan) component.add_input("data:propulsion:turboprop:off_design:itt_limit", np.nan, units="K") component.add_input("data:propulsion:turboprop:off_design:power_limit", np.nan, units="kW") component.add_input("data:propulsion:turboprop:off_design:opr_limit", np.nan) component.add_input("data:aerodynamics:propeller:cruise_level:altitude", np.nan, units="m") component.add_input("data:geometry:propulsion:engine:layout", np.nan) component.add_input("data:geometry:propulsion:engine:count", val=np.nan) component.add_input( "data:aerodynamics:propeller:sea_level:speed", np.full(SPEED_PTS_NB, np.nan), units="m/s", ) component.add_input( "data:aerodynamics:propeller:sea_level:thrust", np.full(THRUST_PTS_NB, np.nan), units="N", ) component.add_input( "data:aerodynamics:propeller:sea_level:thrust_limit", np.full(SPEED_PTS_NB, np.nan), units="N", ) component.add_input( "data:aerodynamics:propeller:sea_level:efficiency", np.full((SPEED_PTS_NB, THRUST_PTS_NB), np.nan), ) component.add_input( "data:aerodynamics:propeller:cruise_level:speed", np.full(SPEED_PTS_NB, np.nan), units="m/s", ) component.add_input( "data:aerodynamics:propeller:cruise_level:thrust", np.full(THRUST_PTS_NB, np.nan), units="N", ) component.add_input( "data:aerodynamics:propeller:cruise_level:thrust_limit", np.full(SPEED_PTS_NB, np.nan), units="N", ) component.add_input( "data:aerodynamics:propeller:cruise_level:efficiency", np.full((SPEED_PTS_NB, THRUST_PTS_NB), np.nan), ) component.add_input( "data:aerodynamics:propeller:installation_effect:effective_efficiency:low_speed", val=1.0, ) component.add_input( "data:aerodynamics:propeller:installation_effect:effective_efficiency:cruise", val=1.0, ) component.add_input( "data:aerodynamics:propeller:installation_effect:effective_advance_ratio", val=1.0, ) component.add_input( "settings:propulsion:turboprop:efficiency:first_compressor_stage", val=0.85 ) component.add_input( "settings:propulsion:turboprop:efficiency:second_compressor_stage", val=0.86 ) component.add_input( "settings:propulsion:turboprop:efficiency:high_pressure_turbine", val=0.86 ) component.add_input("settings:propulsion:turboprop:efficiency:power_turbine", val=0.86) component.add_input( "settings:propulsion:turboprop:efficiency:combustion", val=43.260e6 * 0.95, units="J/kg" ) component.add_input("settings:propulsion:turboprop:efficiency:high_pressure_axe", val=0.98) component.add_input("settings:propulsion:turboprop:pressure_loss:inlet", val=0.8) component.add_input( "settings:propulsion:turboprop:pressure_loss:combustion_chamber", val=0.95 ) component.add_input("settings:propulsion:turboprop:bleed:turbine_cooling", val=0.05) component.add_input( "settings:propulsion:turboprop:electric_power_offtake", val=50 * 745.7, units="W" ) component.add_input("settings:propulsion:turboprop:efficiency:gearbox", val=0.98) component.add_input( "settings:propulsion:turboprop:bleed:inter_compressor", val=0.04, units="kg/s" ) component.add_input("settings:propulsion:turboprop:design_point:mach_exhaust", val=0.4) component.add_input( "settings:propulsion:turboprop:design_point:first_stage_pressure_ratio", val=0.25 )
[docs] @staticmethod def get_model(inputs) -> IPropulsion: """ :param inputs: input parameters that define the engine :return: an :class:`BasicTPEngine` instance """ engine_params = { "power_design": inputs["data:propulsion:turboprop:design_point:power"], "t_41t_design": inputs[ "data:propulsion:turboprop:design_point:turbine_entry_temperature" ], "opr_design": inputs["data:propulsion:turboprop:design_point:OPR"], "cruise_altitude_propeller": inputs[ "data:aerodynamics:propeller:cruise_level:altitude" ], "design_altitude": inputs["data:propulsion:turboprop:design_point:altitude"], "design_mach": inputs["data:propulsion:turboprop:design_point:mach"], "prop_layout": inputs["data:geometry:propulsion:engine:layout"], "bleed_control": inputs["data:propulsion:turboprop:off_design:bleed_usage"], "itt_limit": inputs["data:propulsion:turboprop:off_design:itt_limit"], "power_limit": inputs["data:propulsion:turboprop:off_design:power_limit"], "opr_limit": inputs["data:propulsion:turboprop:off_design:opr_limit"], "speed_SL": inputs["data:aerodynamics:propeller:sea_level:speed"], "thrust_SL": inputs["data:aerodynamics:propeller:sea_level:thrust"], "thrust_limit_SL": inputs["data:aerodynamics:propeller:sea_level:thrust_limit"], "efficiency_SL": inputs["data:aerodynamics:propeller:sea_level:efficiency"], "speed_CL": inputs["data:aerodynamics:propeller:cruise_level:speed"], "thrust_CL": inputs["data:aerodynamics:propeller:cruise_level:thrust"], "thrust_limit_CL": inputs["data:aerodynamics:propeller:cruise_level:thrust_limit"], "efficiency_CL": inputs["data:aerodynamics:propeller:cruise_level:efficiency"], "effective_J": inputs[ "data:aerodynamics:propeller:installation_effect:effective_advance_ratio" ], "effective_efficiency_ls": inputs[ "data:aerodynamics:propeller:installation_effect:effective_efficiency:low_speed" ], "effective_efficiency_cruise": inputs[ "data:aerodynamics:propeller:installation_effect:effective_efficiency:cruise" ], "eta_225": inputs["settings:propulsion:turboprop:efficiency:first_compressor_stage"], "eta_253": inputs["settings:propulsion:turboprop:efficiency:second_compressor_stage"], "eta_445": inputs["settings:propulsion:turboprop:efficiency:high_pressure_turbine"], "eta_455": inputs["settings:propulsion:turboprop:efficiency:power_turbine"], "eta_q": inputs["settings:propulsion:turboprop:efficiency:combustion"], "eta_axe": inputs["settings:propulsion:turboprop:efficiency:high_pressure_axe"], "pi_02": inputs["settings:propulsion:turboprop:pressure_loss:inlet"], "pi_cc": inputs["settings:propulsion:turboprop:pressure_loss:combustion_chamber"], "cooling_ratio": inputs["settings:propulsion:turboprop:bleed:turbine_cooling"], "hp_shaft_power_out": inputs["settings:propulsion:turboprop:electric_power_offtake"], "gearbox_efficiency": inputs["settings:propulsion:turboprop:efficiency:gearbox"], "inter_compressor_bleed": inputs[ "settings:propulsion:turboprop:bleed:inter_compressor" ], "exhaust_mach_design": inputs[ "settings:propulsion:turboprop:design_point:mach_exhaust" ], "pr_1_ratio_design": inputs[ "settings:propulsion:turboprop:design_point:first_stage_pressure_ratio" ], } return FuelEngineSet( BasicTPEngine(**engine_params), inputs["data:geometry:propulsion:engine:count"] )
[docs]@oad.ValidityDomainChecker( { "data:propulsion:turboprop:max_power": ( 180, 10000, ), # power range validity for design point "data:propulsion:turboprop:design_point:turbine_entry_temperature": ( 500.0, 2000.0, ), # turbine entry # temperature validity for design point "data:propulsion:turboprop:design_point:OPR": (1.1, 42.0), # opr validity for design point "data:geometry:propulsion:engine:layout": [1.0, 3.0], # propulsion position (3.0=Nose, # 1.0=Wing) "data:propulsion:turboprop:off_design:bleed_usage": [ 0.0, 1.0, ], # bleed usage at the design point (0.0="low", # 1.0="high") "data:propulsion:turboprop:off_design:itt_limit": (500.0, 1500.0), # turbine entry # temperature validity for off design "data:propulsion:turboprop:off_design:power_limit": ( 180, 10000, ), # power range validity for off design "data:propulsion:turboprop:off_design:opr_limit": ( 1.1, 42.0, ), # opr range validity for off design } ) class OMBasicTPEngineComponent(BaseOMPropulsionComponent): """ Parametric engine model as OpenMDAO component See :class:`BasicICEngine` for more information. """
[docs] def setup(self): super().setup() self.get_wrapper().setup(self)
[docs] @staticmethod def get_wrapper() -> OMBasicTurbopropWrapper: return OMBasicTurbopropWrapper()