Source code for RCAIDE.Library.Methods.Powertrain.Converters.Motor.compute_motor_performance
# RCAIDE/Library/Methods/Powertrain/Converters/Motor/compute_motor_performance.py
#
# Created: Jan 2025, M. Clarke, M. Guidotti
# ----------------------------------------------------------------------------------------------------------------------
# IMPORT
# ----------------------------------------------------------------------------------------------------------------------
# RCAIDE imports
import RCAIDE
from RCAIDE.Framework.Core import Units
# package imports
import numpy as np
# ----------------------------------------------------------------------------------------------------------------------
# compute_omega_and_Q_from_Cp_and_V
# ----------------------------------------------------------------------------------------------------------------------
[docs]
def compute_motor_performance(motor,conditions):
"""
Computes motor performance characteristics including electrical, mechanical and thermal parameters.
Parameters
----------
motor : Converter
Motor component (DC_Motor or PMSM_Motor) for which performance is being computed
motor_conditions : Conditions
Container for motor operating conditions
conditions : Conditions
Mission segment conditions containing freestream properties
Returns
-------
None
Updates motor_conditions in-place with computed performance parameters
Notes
-----
This function handles both PMSM and DC motor types with different computation approaches:
For PMSM motors:
- Computes electromagnetic torque and power
- Accounts for gearbox effects
- Calculates thermal resistances and heat transfer
- Determines cooling flow characteristics
- Evaluates airgap and endspace heat transfer
For DC motors:
- Uses speed-torque relationships
- Accounts for gearbox effects
- Determines overall efficiency
For Both Motors:
- motor.inverse_calculation arg is used to determine parameters that are solved.
- motor.inverse_calculation == False calculates electrical properties (electrical power and voltage) from mechnical properties (rpm and torque)
- motor.inverse_calculation == True calculates mechanial properties (rpm and torque) from electrical properties (electrical power and voltage)
**Major Assumptions**
* Steady state operation
* Uniform temperature distribution
* No magnetic saturation effects
* Linear speed-torque characteristics for DC motors
* Constant material properties
See Also
--------
RCAIDE.Library.Components.Powertrain.Converters.DC_Motor
RCAIDE.Library.Components.Powertrain.Converters.PMSM_Motor
"""
# Unpack
motor_conditions = conditions.energy.converters[motor.tag]
if (type(motor) == RCAIDE.Library.Components.Powertrain.Converters.PMSM_Motor):
if motor.inverse_calculation == False:
Res = motor.resistance
G = motor.gearbox.gear_ratio
I = motor_conditions.inputs.current
V = motor_conditions.inputs.voltage
I_turn = I/motor.number_of_turns # [A] current in each turn
omega = (motor.speed_constant*(V - I*Res)*Units.rpm) /G # [RPM -> rad/s] rotor angular velocity
A = np.pi * ((motor.stator_outer_diameter**2 - motor.stator_inner_diameter**2) / 4) # [m**2] cross-sectional area of the reluctance path perpendicular to length 𝑙
MMF_coil = motor.number_of_turns*I_turn # [A*turns] magnetomotive force applied to the reluctance path for a coil (Eq.14)
R = motor.length_of_path/(A*motor.mu_0*motor.mu_r) # [A*turn/Wb] reluctance of a given path or given reluctant element (Eq.16)
phi = MMF_coil/R # [Wb] magnetic flux through the reluctance path (Eq.12)
B_sign = phi/A # [V*s/m**2] ranges from 0.5 to 1.2, average magnitude of the radial flux density produced by the rotor
A_sign = (motor.winding_factor*I)/(np.pi*motor.stator_inner_diameter) # [-] stator electrical loading (Eq.2)
TQ = (np.pi/2)*(B_sign*A_sign)*(motor.stator_inner_diameter**2)*motor.motor_stack_length # [Nm] torque (Eq.1)
P = omega*TQ # [W] power (Eq.1)
A = np.pi * ((motor.stator_outer_diameter**2 - motor.stator_inner_diameter**2) / 4) # [m**2] cross-sectional area of the reluctance path perpendicular to length 𝑙
R_cond_path = motor.length_of_conductive_path/(motor.thermal_conductivity*A) # [K/W] Conductive Path Thermal Resistance (Eq.68)
if motor.Conduction_laminar_flow == True:
Nu = 0.453*(motor.Re_cooling_flow**0.5)*(motor.Prandtl_number**(1/3)) # Laminar Nusselt number (Eq.71)
else:
Nu = 0.0308*(motor.Re_cooling_flow**(4/5))*(motor.Prandtl_number**(1/3)) # Turbulent Nusselt number (Eq.71)
h = motor.characteristic_length_of_flow*Nu*motor.thermal_conductivity_fluid # [W/m**2*K] convection coefficient of the flow at a liquid to solid interfaced
R_conv_path = 1/(h*A) # [K/W] Fluid Flow Thermal Resistance (Eq.69)
if motor.Re_cooling_flow < 3000:
Nu_cooling_flow = 1.051*np.log(motor.height_of_duct/motor.width_of_duct) + 2.89 # Nusselt number for cooling flow in rectangular ducts and Re_d < 3000 (Eq.72)
h_cooling_flow = motor.characteristic_length_of_flow*Nu_cooling_flow*motor.thermal_conductivity_fluid # [W/m**2*K] convection coefficient of the flow at a liquid to solid interfaced
R_conv_path_cooling_flow = 1/(h_cooling_flow*A) # [K/W] Fluid Flow Thermal Resistance (Eq.69)
else:
if motor.Convection_laminar_flow == True:
f = 64/motor.Re_cooling_flow
else:
f = (0.79*np.log(motor.Re_cooling_flow) - 1.64)**(-2) # Turbulent Moody friction factor (Eq.73)
Nu_cooling_flow = ((f/8)*(motor.Re_cooling_flow - 1000)*motor.Prandtl_number)/(1 + 12.7*((f/8)**0.5)*(motor.Prandtl_number**(2/3) - 1)) # Nusselt number for cooling flow in rectangular ducts and Re_d >= 3000 (Eq.72)
h_cooling_flow = motor.characteristic_length_of_flow*Nu_cooling_flow*motor.thermal_conductivity_fluid # [W/m**2*K] convection coefficient of the flow at a liquid to solid interfaced
R_conv_path_cooling_flow = 1/(h_cooling_flow*A) # [K/W] Fluid Flow Thermal Resistance (Eq.69)
Delta_P_flow = ((f*motor.density_of_fluid*motor.velocity_of_fluid**2)/(2*motor.hydraulic_diameter_of_duct))*motor.length_of_channel # Flow pressure drop (Eq.74)
Loss_cooling = Delta_P_flow*motor.volume_flow_rate_of_fluid # Power needed to pump the fluid through the duct (Eq.75)
if motor.Taylor_number < 41:
Nu_airgap = 2 # Nusselt number for the airgap convection and Ta < 41 (Eq.76)
elif motor.Taylor_number> 41 and motor.Taylor_number < 100:
Nu_airgap = 0.202*(motor.Taylor_number**(0.63))*(motor.Prandtl_number**0.27) # Nusselt number for the airgap convection and 41 < Ta < 100 (Eq.76)
else:
Nu_airgap = 0.386*(motor.Taylor_number**0.5)*(motor.Prandtl_number**0.27) # Nusselt number for the airgap convection and 100 < Ta (Eq.76)
h_airgap = motor.characteristic_length_of_flow*Nu_airgap*motor.thermal_conductivity_fluid # [W/m**2*K] convection coefficient of the flow at a liquid to solid interfaced
R_airgap = 1/(h_airgap*A) # [K/W] Fluid Flow Thermal Resistance (Eq.69)
if motor.axial_gap_to_radius_of_rotor == 0.01:
if motor.Re_airgap < 1e5:
Nu_G = 7.46*motor.Re_airgap**(0.32) # Nusselt number for laminar flow and G = 0.01 (Eq.77)
else:
Nu_G = 0.044*motor.Re_airgap**(0.75) # Nusselt number for turbulent flow and G = 0.01 (Eq.78)
elif motor.axial_gap_to_radius_of_rotor> 0.02 and motor.axial_gap_to_radius_of_rotor < 0.06:
if motor.Re_airgap < 1e5:
Nu_G = 0.5*(1 + 5.47*(10**-4)*np.exp(112*motor.axial_gap_to_radius_of_rotor))*(motor.Re_airgap**0.5) # Nusselt number for laminar flow and G = 0.02 - 0.06 (Eq.77)
else:
Nu_G = 0.5*(12.57*np.exp(-33.18*motor.axial_gap_to_radius_of_rotor))*(motor.Re_airgap**(0.6 + 25*motor.axial_gap_to_radius_of_rotor**(12/7))) # Nusselt number for turbulent flow and G = 0.02 - 0.06 (Eq.78)
elif motor.axial_gap_to_radius_of_rotor > 0.06:
if motor.Re_airgap < 1e5:
Nu_G = 0.35*(motor.Re_airgap**0.5) # Nusselt number for laminar flow and G > 0.06 (Eq.77)
else:
Nu_G = 0.0151*(motor.Re_airgap**0.6) # Nusselt number for turbulent flow and G > 0.06 (Eq.78)
h_endspace = motor.characteristic_length_of_flow*Nu_G*motor.thermal_conductivity_fluid # [W/m**2*K] convection coefficient of the flow at a liquid to solid interfaced
R_endspace = 1/(h_endspace*A) # [K/W] Fluid Flow Thermal Resistance (Eq.69)
Q_cond_path = motor.Delta_T/R_cond_path # heat through a conductive thermal path (Eq.67)
Q_conv_path = motor.Delta_T/R_conv_path # heat through a thermal path (Eq.67)
Q_conv_path_cooling_flow = motor.Delta_T/R_conv_path_cooling_flow # heat through a thermal path (Eq.67)
Q_conv_airgap = motor.Delta_T/R_airgap # heat through a thermal path (Eq.67)
Q_conv_endspace = motor.Delta_T/R_endspace # heat through a thermal path (Eq.67)
omega_gearbox = omega * G
TQ_gearbox = TQ / G
motor_conditions.Q_cond_path = Q_cond_path
motor_conditions.Q_conv_path = Q_conv_path
motor_conditions.Q_conv_path_cooling_flow = Q_conv_path_cooling_flow
motor_conditions.Q_conv_airgap = Q_conv_airgap
motor_conditions.Q_conv_endspace = Q_conv_endspace
motor_conditions.Loss_cooling = Loss_cooling
motor_conditions.outputs.torque = TQ_gearbox
motor_conditions.outputs.omega = omega_gearbox
motor_conditions.outputs.power = P
else:
io = motor.no_load_current
G = motor.gearbox.gear_ratio
omega_gearbox = motor_conditions.outputs.omega
omega = omega_gearbox / G
power = motor_conditions.outputs.power
Kv = motor.speed_constant
D_in = motor.stator_inner_diameter
kw = motor.winding_factor
Res = motor.resistance
L = motor.motor_stack_length
l = motor.length_of_path
mu_0 = motor.mu_0
mu_r = motor.mu_r
Q = power/omega
i = np.sqrt((2*(Q)*l)/(D_in*mu_0*mu_r*L*kw))
v = omega/Kv + ((Q*Kv) + io) * Res
etam = (1-io/i)*(1-i*Res/v)
motor_conditions.inputs.power = v * i
motor_conditions.inputs.voltage = v
motor_conditions.inputs.current = i
motor_conditions.efficiency = etam
else:
if motor.inverse_calculation == False:
G = motor.gearbox.gear_ratio
Res = motor.resistance
Kv = motor.speed_constant
G = motor.gearbox.gear_ratio
io = motor.no_load_current
v = motor_conditions.inputs.voltage
i = motor_conditions.inputs.current
omega = ((v - (Res * i)) * Kv)
Q = ((v- (omega) /Kv)/Res -io)/Kv
etam = (1-io/i)*(1-i*Res/v)
omega_gearbox = omega * G
Q_gearbox = Q / G
motor_conditions.outputs.torque = Q_gearbox
motor_conditions.outputs.omega = omega_gearbox
motor_conditions.outputs.power = omega_gearbox*Q_gearbox
motor_conditions.efficiency = etam
else:
G = motor.gearbox.gear_ratio
omega_gearbox = motor_conditions.outputs.omega
power = motor_conditions.outputs.power
io = motor.no_load_current
Q_gearbox = power / omega_gearbox
omega = omega_gearbox / G
Q = Q_gearbox * G
Res = motor.resistance
Kv = motor.speed_constant
io = motor.no_load_current
v = ((Q *Kv) + io) * Res + omega/Kv
i = (v - (omega)/Kv)/Res
P = i * v
etam = (1-io/i)*(1-i*Res/v)
motor_conditions.inputs.power = v * i
motor_conditions.inputs.voltage = v
motor_conditions.inputs.current = i
motor_conditions.efficiency = etam
return