Source code for fastga.models.propulsion.fuel_propulsion.basicIC_engine.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.propulsion import IPropulsion, BaseOMPropulsionComponent
from fastga.models.propulsion.fuel_propulsion.basicIC_engine.basicIC_engine import BasicICEngine
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.basicIC_engine") class OMBasicICEngineWrapper(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:IC_engine:max_power", np.nan, units="W") component.add_input("data:propulsion:fuel_type", np.nan) component.add_input("data:propulsion:IC_engine:strokes_nb", np.nan) component.add_input("data:geometry:propulsion:engine:layout", np.nan) component.add_input( "settings:propulsion:IC_engine:k_factor_sfc", 1.0, desc="k_factor that can be used to adjust the consumption on engine level to the " "aircraft level", ) 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:cruise_level:altitude", units="m", val=np.nan ) component.add_input("data:geometry:propulsion:engine:count", val=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, )
[docs] @staticmethod def get_model(inputs) -> IPropulsion: """ :param inputs: input parameters that define the engine :return: an :class:`BasicICEngine` instance """ engine_params = { "max_power": inputs["data:propulsion:IC_engine:max_power"], "cruise_altitude_propeller": inputs[ "data:aerodynamics:propeller:cruise_level:altitude" ], "fuel_type": inputs["data:propulsion:fuel_type"], "strokes_nb": inputs["data:propulsion:IC_engine:strokes_nb"], "prop_layout": inputs["data:geometry:propulsion:engine:layout"], "k_factor_sfc": inputs["settings:propulsion:IC_engine:k_factor_sfc"], "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" ], } return FuelEngineSet( BasicICEngine(**engine_params), inputs["data:geometry:propulsion:engine:count"] )
[docs]@oad.ValidityDomainChecker( { "data:propulsion:IC_engine:max_power": (50000, 250000), # power range validity "data:propulsion:fuel_type": [1.0, 2.0], # fuel list "data:propulsion:IC_engine:strokes_nb": [2.0, 4.0], # architecture list "data:geometry:propulsion:engine:layout": [ 1.0, 3.0, ], # propulsion position (3.0=Nose, 1.0=Wing) "data:aerodynamics:propeller:installation_effect:effective_advance_ratio": (0.0, 1.0), "data:aerodynamics:propeller:installation_effect:effective_efficiency:low_speed": ( 0.0, 1.0, ), "data:aerodynamics:propeller:installation_effect:effective_efficiency:cruise": (0.0, 1.0), } ) class OMBasicICEngineComponent(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() -> OMBasicICEngineWrapper: return OMBasicICEngineWrapper()