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:
2025-12-02 02:55:07 +00:00
parent feab2e0bdc
commit 37b3ca912a

View 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)