Source code for RCAIDE.Library.Methods.Powertrain.Converters.Rotor.Design.optimization_setup

# RCAIDE/Methods/Energy/Propulsors/Rotor_Design/optimization_setup.py
# 
# 
# Created:  Jul 2023, M. Clarke 

# ----------------------------------------------------------------------------------------------------------------------
#  IMPORT
# ----------------------------------------------------------------------------------------------------------------------  
 
# RCAIDE Imports  
import RCAIDE 
from RCAIDE.Framework.Core                                                                    import Units, Data   
from RCAIDE.Framework.Optimization.Common                                                     import Nexus       
from RCAIDE.Library.Methods.Powertrain.Converters.Rotor.Design.blade_geometry_setup    import blade_geometry_setup
from RCAIDE.Library.Methods.Powertrain.Converters.Rotor.Design.procedure_setup         import procedure_setup

# Python package imports   
import numpy as np  
    
# ----------------------------------------------------------------------------------------------------------------------  
#  Optimization Setuo 
# ----------------------------------------------------------------------------------------------------------------------    
[docs] def optimization_setup(rotor, number_of_stations, print_iterations): """ Sets up rotor optimization problem including design variables, constraints and objective function using RCAIDE's Nexus optimization framework. Parameters ---------- rotor : RCAIDE.Library.Components.Powertrain.Converters.Rotor Rotor component (Lift_Rotor or Prop_Rotor) with optimization parameters number_of_stations : int Number of radial stations for blade discretization print_iterations : bool Flag to print optimization iterations Returns ------- nexus : RCAIDE.Framework.Optimization.Common.Nexus RCAIDE's optimization framework object with the following attributes: - optimization_problem : Data Optimization problem definition - inputs : numpy.ndarray Design variables - objective : numpy.ndarray Objective function - constraints : numpy.ndarray Constraints - vehicle_configurations : list List of vehicle configurations for analysis - procedure : Data Optimization procedure - print_iterations : bool Flag to print optimization iterations Notes ----- This function configures a complete optimization problem for rotor blade design by: 1. Creating a Nexus optimization framework 2. Validating the rotor type (must be Lift_Rotor or Prop_Rotor) 3. Setting up design variables with bounds and scaling 4. Defining the objective function 5. Establishing constraints for performance and geometry 6. Creating aliases to link optimization variables to vehicle properties 7. Setting up vehicle configurations using blade_geometry_setup 8. Configuring the optimization procedure The design variables include: - chord_r, chord_p, chord_q, chord_t: Parameters defining the chord distribution - twist_r, twist_p, twist_q, twist_t: Parameters defining the twist distribution - hover_tip_mach: Tip Mach number in hover - OEI_tip_mach: Tip Mach number in one-engine-inoperative condition - OEI_collective_pitch: Collective pitch in one-engine-inoperative condition - cruise_tip_mach, cruise_collective_pitch: Additional parameters for prop rotors Constraints ensure: - Thrust and power requirements are met - Blade taper is within reasonable bounds (0.3 to 0.9) - Blade twist is positive - Maximum sectional lift coefficient is below 0.8 - Chord and twist distribution parameters maintain reasonable ratios **Major Assumptions** * Minimum allowable blade taper: 0.3 * Maximum allowable blade taper: 0.9 * Maximum sectional lift coefficient: 0.8 See Also -------- RCAIDE.Library.Methods.Powertrain.Converters.Rotor.Design.blade_geometry_setup RCAIDE.Library.Methods.Powertrain.Converters.Rotor.Design.procedure_setup """ nexus = Nexus() problem = Data() nexus.optimization_problem = problem if type(rotor) != RCAIDE.Library.Components.Powertrain.Converters.Prop_Rotor or type(rotor) != RCAIDE.Library.Components.Powertrain.Converters.Lift_Rotor: assert('rotor must be of Lift-Rotor or Prop-Rotor class') if type(rotor) == RCAIDE.Library.Components.Powertrain.Converters.Prop_Rotor: nexus.prop_rotor_flag = True else: nexus.prop_rotor_flag = False # ------------------------------------------------------------------- # Inputs # ------------------------------------------------------------------- R = rotor.tip_radius tm_ll_h = rotor.optimization_parameters.tip_mach_range[0] tm_ul_h = rotor.optimization_parameters.tip_mach_range[1] tm_0_h = (tm_ul_h + tm_ll_h)/2 if nexus.prop_rotor_flag: tm_ll_c = rotor.optimization_parameters.tip_mach_range[0] tm_ul_c = rotor.optimization_parameters.tip_mach_range[1] inputs = [] inputs.append([ 'chord_r' , 0.1*R , 0.05*R , 0.2*R , 1.0 , 1*Units.less]) inputs.append([ 'chord_p' , 2 , 0.25 , 2.0 , 1.0 , 1*Units.less]) inputs.append([ 'chord_q' , 1 , 0.25 , 1.5 , 1.0 , 1*Units.less]) inputs.append([ 'chord_t' , 0.05*R , 0.02*R , 0.1*R , 1.0 , 1*Units.less]) inputs.append([ 'twist_r' , np.pi/6 , 0 , np.pi/4 , 1.0 , 1*Units.less]) inputs.append([ 'twist_p' , 1 , 0.25 , 2.0 , 1.0 , 1*Units.less]) inputs.append([ 'twist_q' , 0.5 , 0.25 , 1.5 , 1.0 , 1*Units.less]) inputs.append([ 'twist_t' , np.pi/6 , 0 , np.pi/4 , 1.0 , 1*Units.less]) inputs.append([ 'hover_tip_mach' , tm_0_h , tm_ll_h , tm_ul_h , 1.0 , 1*Units.less]) inputs.append([ 'OEI_tip_mach' , tm_0_h , tm_ll_h , 0.85 , 1.0 , 1*Units.less]) inputs.append([ 'OEI_collective_pitch' , np.pi/6 , -np.pi/5 , np.pi/5 , 1.0 , 1*Units.less]) if nexus.prop_rotor_flag: inputs.append([ 'cruise_tip_mach' , tm_ll_c , tm_ll_c , tm_ul_c , 1.0 , 1*Units.less]) inputs.append([ 'cuise_collective_pitch' , np.pi/8 , -np.pi/5 , np.pi/5 , 1.0 , 1*Units.less]) problem.inputs = np.array(inputs,dtype=object) # ------------------------------------------------------------------- # Objective # ------------------------------------------------------------------- problem.objective = np.array([ [ 'objective' , 1.0 , 1*Units.less] ],dtype=object) # ------------------------------------------------------------------- # Constraints # ------------------------------------------------------------------- constraints = [] constraints.append([ 'hover_thrust_pow_res' , '<' , 1E-3 , 1.0 , 1*Units.less]) constraints.append([ 'blade_taper_constraint_1' , '>' , 0.3 , 1.0 , 1*Units.less]) constraints.append([ 'blade_taper_constraint_2' , '<' , 0.9 , 1.0 , 1*Units.less]) constraints.append([ 'blade_twist_constraint' , '>' , 0.0 , 1.0 , 1*Units.less]) constraints.append([ 'max_sectional_cl_hov' , '<' , 0.8 , 1.0 , 1*Units.less]) constraints.append([ 'chord_p_to_q_ratio' , '>' , 0.5 , 1.0 , 1*Units.less]) constraints.append([ 'twist_p_to_q_ratio' , '>' , 0.5 , 1.0 , 1*Units.less]) constraints.append([ 'OEI_hov_thrust_pow_res' , '<' , 1E-3 , 1.0 , 1*Units.less]) if nexus.prop_rotor_flag: constraints.append([ 'cruise_thrust_pow_res' , '<' , 1E-3 , 1.0 , 1*Units.less]) constraints.append([ 'max_sectional_cl_cruise' , '<' , 0.8 , 1.0 , 1*Units.less]) problem.constraints = np.array(constraints,dtype=object) # ------------------------------------------------------------------- # Aliases # ------------------------------------------------------------------- aliases = [] aliases.append([ 'chord_r' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.chord_r' ]) aliases.append([ 'chord_p' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.chord_p' ]) aliases.append([ 'chord_q' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.chord_q' ]) aliases.append([ 'chord_t' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.chord_t' ]) aliases.append([ 'twist_r' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.twist_r' ]) aliases.append([ 'twist_p' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.twist_p' ]) aliases.append([ 'twist_q' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.twist_q' ]) aliases.append([ 'twist_t' , 'vehicle_configurations.*.networks.electric.propulsors.electric_rotor.rotor.twist_t' ]) aliases.append([ 'hover_tip_mach' , 'vehicle_configurations.hover.networks.electric.propulsors.electric_rotor.rotor.hover.design_tip_mach' ]) aliases.append([ 'objective' , 'summary.objective' ]) aliases.append([ 'hover_thrust_pow_res' , 'summary.hover_thrust_power_residual' ]) aliases.append([ 'blade_taper_constraint_1' , 'summary.blade_taper_constraint_1']) aliases.append([ 'blade_taper_constraint_2' , 'summary.blade_taper_constraint_2']) aliases.append([ 'blade_twist_constraint' , 'summary.blade_twist_constraint']) aliases.append([ 'max_sectional_cl_hov' , 'summary.max_sectional_cl_hover']) aliases.append([ 'chord_p_to_q_ratio' , 'summary.chord_p_to_q_ratio' ]) aliases.append([ 'twist_p_to_q_ratio' , 'summary.twist_p_to_q_ratio' ]) aliases.append([ 'OEI_hov_thrust_pow_res' , 'summary.oei_thrust_power_residual' ]) aliases.append([ 'OEI_collective_pitch' , 'vehicle_configurations.oei.networks.electric.propulsors.electric_rotor.rotor.oei.design_blade_pitch_command' ]) aliases.append([ 'OEI_tip_mach' , 'vehicle_configurations.oei.networks.electric.propulsors.electric_rotor.rotor.oei.design_tip_mach' ]) if nexus.prop_rotor_flag: aliases.append([ 'cruise_tip_mach' , 'vehicle_configurations.cruise.networks.electric.propulsors.electric_rotor.rotor.cruise.design_tip_mach' ]) aliases.append([ 'cuise_collective_pitch' , 'vehicle_configurations.cruise.networks.electric.propulsors.electric_rotor.rotor.cruise.design_blade_pitch_command' ]) aliases.append([ 'cruise_thrust_pow_res' , 'summary.cruise_thrust_power_residual' ]) aliases.append([ 'max_sectional_cl_cruise', 'summary.max_sectional_cl_cruise']) problem.aliases = aliases # ------------------------------------------------------------------- # Vehicles # ------------------------------------------------------------------- nexus.vehicle_configurations = blade_geometry_setup(rotor,number_of_stations) # ------------------------------------------------------------------- # Analyses # ------------------------------------------------------------------- nexus.analyses = None # ------------------------------------------------------------------- # Missions # ------------------------------------------------------------------- nexus.missions = None # ------------------------------------------------------------------- # Procedure # ------------------------------------------------------------------- nexus.print_iterations = print_iterations nexus.procedure = procedure_setup() # ------------------------------------------------------------------- # Summary # ------------------------------------------------------------------- nexus.summary = Data() nexus.results.hover = Data() nexus.results.cruise = Data() nexus.results.oei = Data() return nexus