Implement thermal calculation functions
Pure functions for first-order thermal response calculations: - Temperature derivative and update using Euler integration - Case temperature with self-heating via θ_ca - Junction temperature calculation via θ_jc - Steady-state junction temperature helper
This commit is contained in:
193
src/py_dvt_ate/simulation/physics/thermal.py
Normal file
193
src/py_dvt_ate/simulation/physics/thermal.py
Normal file
@@ -0,0 +1,193 @@
|
||||
"""Thermal calculation functions for physics simulation.
|
||||
|
||||
Pure functions implementing first-order thermal response calculations
|
||||
for the coupled thermal-electrical simulation.
|
||||
|
||||
All temperatures are in degrees Celsius.
|
||||
All time values are in seconds.
|
||||
All power values are in watts.
|
||||
All thermal resistances are in degrees Celsius per watt (°C/W).
|
||||
"""
|
||||
|
||||
|
||||
def calculate_temperature_derivative(
|
||||
current_temperature: float,
|
||||
target_temperature: float,
|
||||
time_constant: float,
|
||||
) -> float:
|
||||
"""Calculate the rate of temperature change for first-order response.
|
||||
|
||||
Implements: dT/dt = (T_target - T_current) / τ
|
||||
|
||||
Args:
|
||||
current_temperature: Current temperature in degrees Celsius.
|
||||
target_temperature: Target temperature in degrees Celsius.
|
||||
time_constant: Thermal time constant in seconds.
|
||||
|
||||
Returns:
|
||||
Rate of temperature change in degrees Celsius per second.
|
||||
|
||||
Raises:
|
||||
ValueError: If time_constant is not positive.
|
||||
"""
|
||||
if time_constant <= 0:
|
||||
msg = f"Time constant must be positive, got {time_constant}"
|
||||
raise ValueError(msg)
|
||||
|
||||
return (target_temperature - current_temperature) / time_constant
|
||||
|
||||
|
||||
def update_temperature(
|
||||
current_temperature: float,
|
||||
target_temperature: float,
|
||||
time_constant: float,
|
||||
dt: float,
|
||||
) -> float:
|
||||
"""Calculate new temperature after a time step using Euler integration.
|
||||
|
||||
Args:
|
||||
current_temperature: Current temperature in degrees Celsius.
|
||||
target_temperature: Target temperature in degrees Celsius.
|
||||
time_constant: Thermal time constant in seconds.
|
||||
dt: Time step in seconds.
|
||||
|
||||
Returns:
|
||||
New temperature in degrees Celsius after the time step.
|
||||
|
||||
Raises:
|
||||
ValueError: If time_constant or dt is not positive.
|
||||
"""
|
||||
if dt <= 0:
|
||||
msg = f"Time step must be positive, got {dt}"
|
||||
raise ValueError(msg)
|
||||
|
||||
derivative = calculate_temperature_derivative(
|
||||
current_temperature, target_temperature, time_constant
|
||||
)
|
||||
return current_temperature + derivative * dt
|
||||
|
||||
|
||||
def calculate_case_temperature_derivative(
|
||||
case_temperature: float,
|
||||
ambient_temperature: float,
|
||||
power_dissipation: float,
|
||||
time_constant: float,
|
||||
theta_ca: float,
|
||||
) -> float:
|
||||
"""Calculate rate of case temperature change including self-heating.
|
||||
|
||||
Implements: dT_case/dt = (T_ambient - T_case + P_diss × θ_ca) / τ_case
|
||||
|
||||
The case temperature is driven by:
|
||||
- Convection/conduction to ambient (chamber) temperature
|
||||
- Self-heating from power dissipation through case-to-ambient thermal resistance
|
||||
|
||||
Args:
|
||||
case_temperature: Current case temperature in degrees Celsius.
|
||||
ambient_temperature: Ambient (chamber) temperature in degrees Celsius.
|
||||
power_dissipation: Power dissipated by the device in watts.
|
||||
time_constant: Case thermal time constant in seconds.
|
||||
theta_ca: Thermal resistance from case to ambient in °C/W.
|
||||
|
||||
Returns:
|
||||
Rate of case temperature change in degrees Celsius per second.
|
||||
|
||||
Raises:
|
||||
ValueError: If time_constant is not positive.
|
||||
"""
|
||||
if time_constant <= 0:
|
||||
msg = f"Time constant must be positive, got {time_constant}"
|
||||
raise ValueError(msg)
|
||||
|
||||
# The effective target includes self-heating contribution
|
||||
thermal_drive = ambient_temperature - case_temperature + power_dissipation * theta_ca
|
||||
return thermal_drive / time_constant
|
||||
|
||||
|
||||
def update_case_temperature(
|
||||
case_temperature: float,
|
||||
ambient_temperature: float,
|
||||
power_dissipation: float,
|
||||
time_constant: float,
|
||||
theta_ca: float,
|
||||
dt: float,
|
||||
) -> float:
|
||||
"""Calculate new case temperature after a time step.
|
||||
|
||||
Args:
|
||||
case_temperature: Current case temperature in degrees Celsius.
|
||||
ambient_temperature: Ambient (chamber) temperature in degrees Celsius.
|
||||
power_dissipation: Power dissipated by the device in watts.
|
||||
time_constant: Case thermal time constant in seconds.
|
||||
theta_ca: Thermal resistance from case to ambient in °C/W.
|
||||
dt: Time step in seconds.
|
||||
|
||||
Returns:
|
||||
New case temperature in degrees Celsius after the time step.
|
||||
|
||||
Raises:
|
||||
ValueError: If time_constant or dt is not positive.
|
||||
"""
|
||||
if dt <= 0:
|
||||
msg = f"Time step must be positive, got {dt}"
|
||||
raise ValueError(msg)
|
||||
|
||||
derivative = calculate_case_temperature_derivative(
|
||||
case_temperature,
|
||||
ambient_temperature,
|
||||
power_dissipation,
|
||||
time_constant,
|
||||
theta_ca,
|
||||
)
|
||||
return case_temperature + derivative * dt
|
||||
|
||||
|
||||
def calculate_junction_temperature(
|
||||
case_temperature: float,
|
||||
power_dissipation: float,
|
||||
theta_jc: float,
|
||||
) -> float:
|
||||
"""Calculate junction temperature from case temperature and power.
|
||||
|
||||
The junction temperature is assumed to respond instantaneously to
|
||||
changes in case temperature and power dissipation (no thermal mass
|
||||
at the die level for this simplified model).
|
||||
|
||||
Implements: T_junction = T_case + P_diss × θ_jc
|
||||
|
||||
Args:
|
||||
case_temperature: Case temperature in degrees Celsius.
|
||||
power_dissipation: Power dissipated by the device in watts.
|
||||
theta_jc: Thermal resistance from junction to case in °C/W.
|
||||
|
||||
Returns:
|
||||
Junction temperature in degrees Celsius.
|
||||
"""
|
||||
return case_temperature + power_dissipation * theta_jc
|
||||
|
||||
|
||||
def calculate_steady_state_junction_temperature(
|
||||
ambient_temperature: float,
|
||||
power_dissipation: float,
|
||||
theta_jc: float,
|
||||
theta_ca: float,
|
||||
) -> float:
|
||||
"""Calculate the steady-state junction temperature.
|
||||
|
||||
At steady state, the case temperature reaches equilibrium where
|
||||
the heat flow through θ_ca equals the power dissipation.
|
||||
|
||||
T_case_ss = T_ambient + P_diss × θ_ca
|
||||
T_junction_ss = T_case_ss + P_diss × θ_jc
|
||||
= T_ambient + P_diss × (θ_jc + θ_ca)
|
||||
|
||||
Args:
|
||||
ambient_temperature: Ambient (chamber) temperature in degrees Celsius.
|
||||
power_dissipation: Power dissipated by the device in watts.
|
||||
theta_jc: Thermal resistance from junction to case in °C/W.
|
||||
theta_ca: Thermal resistance from case to ambient in °C/W.
|
||||
|
||||
Returns:
|
||||
Steady-state junction temperature in degrees Celsius.
|
||||
"""
|
||||
return ambient_temperature + power_dissipation * (theta_jc + theta_ca)
|
||||
Reference in New Issue
Block a user