Spaces:
Sleeping
Sleeping
Upload heat_transfer.py
Browse files- utils/heat_transfer.py +36 -36
utils/heat_transfer.py
CHANGED
|
@@ -158,7 +158,7 @@ class SolarCalculations:
|
|
| 158 |
solar_altitude: Solar altitude angle in degrees
|
| 159 |
|
| 160 |
Returns:
|
| 161 |
-
Direct normal irradiance in W/m
|
| 162 |
"""
|
| 163 |
self.validate_angle(solar_altitude, "Solar altitude", 0, 90)
|
| 164 |
if solar_altitude <= 0:
|
|
@@ -172,11 +172,11 @@ class SolarCalculations:
|
|
| 172 |
Calculate diffuse horizontal irradiance.
|
| 173 |
|
| 174 |
Args:
|
| 175 |
-
dni: Direct normal irradiance in W/m
|
| 176 |
solar_altitude: Solar altitude angle in degrees
|
| 177 |
|
| 178 |
Returns:
|
| 179 |
-
Diffuse horizontal irradiance in W/m
|
| 180 |
"""
|
| 181 |
self.validate_angle(solar_altitude, "Solar altitude", 0, 90)
|
| 182 |
if solar_altitude <= 0:
|
|
@@ -188,13 +188,13 @@ class SolarCalculations:
|
|
| 188 |
Calculate total irradiance on a tilted surface.
|
| 189 |
|
| 190 |
Args:
|
| 191 |
-
dni: Direct normal irradiance in W/m
|
| 192 |
-
dhi: Diffuse horizontal irradiance in W/m
|
| 193 |
incident_angle: Angle of incidence in degrees
|
| 194 |
surface_tilt: Surface tilt angle in degrees
|
| 195 |
|
| 196 |
Returns:
|
| 197 |
-
Total irradiance in W/m
|
| 198 |
"""
|
| 199 |
self.validate_angle(incident_angle, "Incident angle", 0, 90)
|
| 200 |
self.validate_angle(surface_tilt, "Surface tilt", 0, 180)
|
|
@@ -220,8 +220,8 @@ class HeatTransferCalculations:
|
|
| 220 |
|
| 221 |
Args:
|
| 222 |
temp: Temperature in °C
|
| 223 |
-
area: Area in m
|
| 224 |
-
flow_rate: Flow rate in m
|
| 225 |
|
| 226 |
Raises:
|
| 227 |
ValueError: If inputs are out of acceptable ranges
|
|
@@ -229,24 +229,24 @@ class HeatTransferCalculations:
|
|
| 229 |
if not -50 <= temp <= 60:
|
| 230 |
raise ValueError(f"Temperature {temp}°C is outside valid range (-50 to 60°C)")
|
| 231 |
if area < 0:
|
| 232 |
-
raise ValueError(f"Area {area}m
|
| 233 |
if flow_rate < 0:
|
| 234 |
-
raise ValueError(f"Flow rate {flow_rate}m
|
| 235 |
|
| 236 |
def conduction_heat_transfer(self, u_value: float, area: float, delta_t: float) -> float:
|
| 237 |
"""
|
| 238 |
Calculate heat transfer by conduction.
|
| 239 |
|
| 240 |
Args:
|
| 241 |
-
u_value: Overall heat transfer coefficient in W/(m
|
| 242 |
-
area: Surface area in m
|
| 243 |
delta_t: Temperature difference in °C
|
| 244 |
|
| 245 |
Returns:
|
| 246 |
Heat transfer rate in W
|
| 247 |
"""
|
| 248 |
if u_value < 0:
|
| 249 |
-
raise ValueError(f"U-value {u_value} W/(m
|
| 250 |
self.validate_inputs(delta_t, area)
|
| 251 |
return u_value * area * delta_t
|
| 252 |
|
|
@@ -255,15 +255,15 @@ class HeatTransferCalculations:
|
|
| 255 |
Calculate heat transfer by convection.
|
| 256 |
|
| 257 |
Args:
|
| 258 |
-
h: Convective heat transfer coefficient in W/(m
|
| 259 |
-
area: Surface area in m
|
| 260 |
delta_t: Temperature difference in °C
|
| 261 |
|
| 262 |
Returns:
|
| 263 |
Heat transfer rate in W
|
| 264 |
"""
|
| 265 |
if h < 0:
|
| 266 |
-
raise ValueError(f"Convective coefficient {h} W/(m
|
| 267 |
self.validate_inputs(delta_t, area)
|
| 268 |
return h * area * delta_t
|
| 269 |
|
|
@@ -273,7 +273,7 @@ class HeatTransferCalculations:
|
|
| 273 |
|
| 274 |
Args:
|
| 275 |
emissivity: Surface emissivity (0-1)
|
| 276 |
-
area: Surface area in m
|
| 277 |
t_surface: Surface temperature in °C
|
| 278 |
t_surroundings: Surroundings temperature in °C
|
| 279 |
|
|
@@ -285,7 +285,7 @@ class HeatTransferCalculations:
|
|
| 285 |
self.validate_inputs(t_surface, area)
|
| 286 |
self.validate_inputs(t_surroundings)
|
| 287 |
|
| 288 |
-
sigma = 5.67e-8 # Stefan-Boltzmann constant in W/(m
|
| 289 |
t_s = t_surface + 273.15
|
| 290 |
t_sur = t_surroundings + 273.15
|
| 291 |
return emissivity * sigma * area * (t_s**4 - t_sur**4)
|
|
@@ -316,14 +316,14 @@ class HeatTransferCalculations:
|
|
| 316 |
Calculate sensible heat transfer due to infiltration or ventilation.
|
| 317 |
|
| 318 |
Args:
|
| 319 |
-
flow_rate: Air flow rate in m
|
| 320 |
delta_t: Temperature difference in °C
|
| 321 |
|
| 322 |
Returns:
|
| 323 |
Sensible heat transfer rate in W
|
| 324 |
"""
|
| 325 |
self.validate_inputs(delta_t, flow_rate=flow_rate)
|
| 326 |
-
rho = 1.2 # Air density in kg/m
|
| 327 |
cp = 1005 # Specific heat of air in J/(kg·K)
|
| 328 |
return flow_rate * rho * cp * delta_t
|
| 329 |
|
|
@@ -332,14 +332,14 @@ class HeatTransferCalculations:
|
|
| 332 |
Calculate latent heat transfer due to infiltration or ventilation.
|
| 333 |
|
| 334 |
Args:
|
| 335 |
-
flow_rate: Air flow rate in m
|
| 336 |
delta_w: Humidity ratio difference in kg/kg
|
| 337 |
|
| 338 |
Returns:
|
| 339 |
Latent heat transfer rate in W
|
| 340 |
"""
|
| 341 |
self.validate_inputs(0, flow_rate=flow_rate)
|
| 342 |
-
rho = 1.2 # Air density in kg/m
|
| 343 |
h_fg = 2501000 # Latent heat of vaporization in J/kg
|
| 344 |
return flow_rate * rho * h_fg * delta_w
|
| 345 |
|
|
@@ -359,7 +359,7 @@ class HeatTransferCalculations:
|
|
| 359 |
if not 0 <= wind_coefficient <= 1:
|
| 360 |
raise ValueError(f"Wind coefficient {wind_coefficient} must be between 0 and 1")
|
| 361 |
|
| 362 |
-
rho = 1.2 # Air density in kg/m
|
| 363 |
return 0.5 * wind_coefficient * rho * wind_speed**2
|
| 364 |
|
| 365 |
def stack_pressure_difference(self, height: float, indoor_temp: float, outdoor_temp: float) -> float:
|
|
@@ -379,8 +379,8 @@ class HeatTransferCalculations:
|
|
| 379 |
if indoor_temp <= 0 or outdoor_temp <= 0:
|
| 380 |
raise ValueError("Temperatures must be positive in Kelvin")
|
| 381 |
|
| 382 |
-
g = 9.81 # Gravitational acceleration in m/s
|
| 383 |
-
rho = 1.2 # Air density in kg/m
|
| 384 |
delta_t = abs(indoor_temp - outdoor_temp)
|
| 385 |
t_avg = (indoor_temp + outdoor_temp) / 2
|
| 386 |
return rho * g * height * delta_t / t_avg
|
|
@@ -407,11 +407,11 @@ class HeatTransferCalculations:
|
|
| 407 |
|
| 408 |
Args:
|
| 409 |
crack_length: Total crack length in m
|
| 410 |
-
coefficient: Flow coefficient in m
|
| 411 |
pressure_difference: Pressure difference in Pa
|
| 412 |
|
| 413 |
Returns:
|
| 414 |
-
Infiltration flow rate in m
|
| 415 |
"""
|
| 416 |
if crack_length < 0:
|
| 417 |
raise ValueError(f"Crack length {crack_length} m cannot be negative")
|
|
@@ -430,20 +430,20 @@ class HeatTransferCalculations:
|
|
| 430 |
|
| 431 |
Args:
|
| 432 |
outdoor_temp: Outdoor air temperature in °C
|
| 433 |
-
solar_irradiance: Solar irradiance on surface in W/m
|
| 434 |
surface_absorptivity: Surface absorptivity (0-1)
|
| 435 |
-
surface_resistance: Surface resistance in m
|
| 436 |
|
| 437 |
Returns:
|
| 438 |
Sol-air temperature in °C
|
| 439 |
"""
|
| 440 |
self.validate_inputs(outdoor_temp)
|
| 441 |
if solar_irradiance < 0:
|
| 442 |
-
raise ValueError(f"Solar irradiance {solar_irradiance} W/m
|
| 443 |
if not 0 <= surface_absorptivity <= 1:
|
| 444 |
raise ValueError(f"Surface absorptivity {surface_absorptivity} must be between 0 and 1")
|
| 445 |
if surface_resistance < 0:
|
| 446 |
-
raise ValueError(f"Surface resistance {surface_resistance} m
|
| 447 |
|
| 448 |
h_ext = 1 / surface_resistance # External convective coefficient
|
| 449 |
delta_t_rad = surface_absorptivity * solar_irradiance / h_ext
|
|
@@ -455,8 +455,8 @@ class HeatTransferCalculations:
|
|
| 455 |
Calculate solar heat gain through a surface.
|
| 456 |
|
| 457 |
Args:
|
| 458 |
-
irradiance: Solar irradiance on surface in W/m
|
| 459 |
-
area: Surface area in m
|
| 460 |
shgc: Solar heat gain coefficient (0-1)
|
| 461 |
shading_coefficient: Shading coefficient (0-1)
|
| 462 |
|
|
@@ -465,7 +465,7 @@ class HeatTransferCalculations:
|
|
| 465 |
"""
|
| 466 |
self.validate_inputs(0, area)
|
| 467 |
if irradiance < 0:
|
| 468 |
-
raise ValueError(f"Irradiance {irradiance} W/m
|
| 469 |
if not 0 <= shgc <= 1:
|
| 470 |
raise ValueError(f"SHGC {shgc} must be between 0 and 1")
|
| 471 |
if not 0 <= shading_coefficient <= 1:
|
|
@@ -495,8 +495,8 @@ if __name__ == "__main__":
|
|
| 495 |
print(f"Solar Azimuth: {azimuth:.2f}°")
|
| 496 |
|
| 497 |
# Example heat transfer calculation
|
| 498 |
-
u_value = 0.5 # W/(m
|
| 499 |
-
area = 20.0 # m
|
| 500 |
delta_t = 10.0 # °C
|
| 501 |
conduction = heat_transfer_calculator.conduction_heat_transfer(u_value, area, delta_t)
|
| 502 |
print(f"Conduction Heat Transfer: {conduction:.2f} W")
|
|
|
|
| 158 |
solar_altitude: Solar altitude angle in degrees
|
| 159 |
|
| 160 |
Returns:
|
| 161 |
+
Direct normal irradiance in W/m²
|
| 162 |
"""
|
| 163 |
self.validate_angle(solar_altitude, "Solar altitude", 0, 90)
|
| 164 |
if solar_altitude <= 0:
|
|
|
|
| 172 |
Calculate diffuse horizontal irradiance.
|
| 173 |
|
| 174 |
Args:
|
| 175 |
+
dni: Direct normal irradiance in W/m²
|
| 176 |
solar_altitude: Solar altitude angle in degrees
|
| 177 |
|
| 178 |
Returns:
|
| 179 |
+
Diffuse horizontal irradiance in W/m²
|
| 180 |
"""
|
| 181 |
self.validate_angle(solar_altitude, "Solar altitude", 0, 90)
|
| 182 |
if solar_altitude <= 0:
|
|
|
|
| 188 |
Calculate total irradiance on a tilted surface.
|
| 189 |
|
| 190 |
Args:
|
| 191 |
+
dni: Direct normal irradiance in W/m²
|
| 192 |
+
dhi: Diffuse horizontal irradiance in W/m²
|
| 193 |
incident_angle: Angle of incidence in degrees
|
| 194 |
surface_tilt: Surface tilt angle in degrees
|
| 195 |
|
| 196 |
Returns:
|
| 197 |
+
Total irradiance in W/m²
|
| 198 |
"""
|
| 199 |
self.validate_angle(incident_angle, "Incident angle", 0, 90)
|
| 200 |
self.validate_angle(surface_tilt, "Surface tilt", 0, 180)
|
|
|
|
| 220 |
|
| 221 |
Args:
|
| 222 |
temp: Temperature in °C
|
| 223 |
+
area: Area in m²
|
| 224 |
+
flow_rate: Flow rate in m³/s
|
| 225 |
|
| 226 |
Raises:
|
| 227 |
ValueError: If inputs are out of acceptable ranges
|
|
|
|
| 229 |
if not -50 <= temp <= 60:
|
| 230 |
raise ValueError(f"Temperature {temp}°C is outside valid range (-50 to 60°C)")
|
| 231 |
if area < 0:
|
| 232 |
+
raise ValueError(f"Area {area}m² cannot be negative")
|
| 233 |
if flow_rate < 0:
|
| 234 |
+
raise ValueError(f"Flow rate {flow_rate}m³/s cannot be negative")
|
| 235 |
|
| 236 |
def conduction_heat_transfer(self, u_value: float, area: float, delta_t: float) -> float:
|
| 237 |
"""
|
| 238 |
Calculate heat transfer by conduction.
|
| 239 |
|
| 240 |
Args:
|
| 241 |
+
u_value: Overall heat transfer coefficient in W/(m²·K)
|
| 242 |
+
area: Surface area in m²
|
| 243 |
delta_t: Temperature difference in °C
|
| 244 |
|
| 245 |
Returns:
|
| 246 |
Heat transfer rate in W
|
| 247 |
"""
|
| 248 |
if u_value < 0:
|
| 249 |
+
raise ValueError(f"U-value {u_value} W/(m²·K) cannot be negative")
|
| 250 |
self.validate_inputs(delta_t, area)
|
| 251 |
return u_value * area * delta_t
|
| 252 |
|
|
|
|
| 255 |
Calculate heat transfer by convection.
|
| 256 |
|
| 257 |
Args:
|
| 258 |
+
h: Convective heat transfer coefficient in W/(m²·K)
|
| 259 |
+
area: Surface area in m²
|
| 260 |
delta_t: Temperature difference in °C
|
| 261 |
|
| 262 |
Returns:
|
| 263 |
Heat transfer rate in W
|
| 264 |
"""
|
| 265 |
if h < 0:
|
| 266 |
+
raise ValueError(f"Convective coefficient {h} W/(m²·K) cannot be negative")
|
| 267 |
self.validate_inputs(delta_t, area)
|
| 268 |
return h * area * delta_t
|
| 269 |
|
|
|
|
| 273 |
|
| 274 |
Args:
|
| 275 |
emissivity: Surface emissivity (0-1)
|
| 276 |
+
area: Surface area in m²
|
| 277 |
t_surface: Surface temperature in °C
|
| 278 |
t_surroundings: Surroundings temperature in °C
|
| 279 |
|
|
|
|
| 285 |
self.validate_inputs(t_surface, area)
|
| 286 |
self.validate_inputs(t_surroundings)
|
| 287 |
|
| 288 |
+
sigma = 5.67e-8 # Stefan-Boltzmann constant in W/(m²·K⁴)
|
| 289 |
t_s = t_surface + 273.15
|
| 290 |
t_sur = t_surroundings + 273.15
|
| 291 |
return emissivity * sigma * area * (t_s**4 - t_sur**4)
|
|
|
|
| 316 |
Calculate sensible heat transfer due to infiltration or ventilation.
|
| 317 |
|
| 318 |
Args:
|
| 319 |
+
flow_rate: Air flow rate in m³/s
|
| 320 |
delta_t: Temperature difference in °C
|
| 321 |
|
| 322 |
Returns:
|
| 323 |
Sensible heat transfer rate in W
|
| 324 |
"""
|
| 325 |
self.validate_inputs(delta_t, flow_rate=flow_rate)
|
| 326 |
+
rho = 1.2 # Air density in kg/m³
|
| 327 |
cp = 1005 # Specific heat of air in J/(kg·K)
|
| 328 |
return flow_rate * rho * cp * delta_t
|
| 329 |
|
|
|
|
| 332 |
Calculate latent heat transfer due to infiltration or ventilation.
|
| 333 |
|
| 334 |
Args:
|
| 335 |
+
flow_rate: Air flow rate in m³/s
|
| 336 |
delta_w: Humidity ratio difference in kg/kg
|
| 337 |
|
| 338 |
Returns:
|
| 339 |
Latent heat transfer rate in W
|
| 340 |
"""
|
| 341 |
self.validate_inputs(0, flow_rate=flow_rate)
|
| 342 |
+
rho = 1.2 # Air density in kg/m³
|
| 343 |
h_fg = 2501000 # Latent heat of vaporization in J/kg
|
| 344 |
return flow_rate * rho * h_fg * delta_w
|
| 345 |
|
|
|
|
| 359 |
if not 0 <= wind_coefficient <= 1:
|
| 360 |
raise ValueError(f"Wind coefficient {wind_coefficient} must be between 0 and 1")
|
| 361 |
|
| 362 |
+
rho = 1.2 # Air density in kg/m³
|
| 363 |
return 0.5 * wind_coefficient * rho * wind_speed**2
|
| 364 |
|
| 365 |
def stack_pressure_difference(self, height: float, indoor_temp: float, outdoor_temp: float) -> float:
|
|
|
|
| 379 |
if indoor_temp <= 0 or outdoor_temp <= 0:
|
| 380 |
raise ValueError("Temperatures must be positive in Kelvin")
|
| 381 |
|
| 382 |
+
g = 9.81 # Gravitational acceleration in m/s²
|
| 383 |
+
rho = 1.2 # Air density in kg/m³
|
| 384 |
delta_t = abs(indoor_temp - outdoor_temp)
|
| 385 |
t_avg = (indoor_temp + outdoor_temp) / 2
|
| 386 |
return rho * g * height * delta_t / t_avg
|
|
|
|
| 407 |
|
| 408 |
Args:
|
| 409 |
crack_length: Total crack length in m
|
| 410 |
+
coefficient: Flow coefficient in m³/(s·m·Pa^n)
|
| 411 |
pressure_difference: Pressure difference in Pa
|
| 412 |
|
| 413 |
Returns:
|
| 414 |
+
Infiltration flow rate in m³/s
|
| 415 |
"""
|
| 416 |
if crack_length < 0:
|
| 417 |
raise ValueError(f"Crack length {crack_length} m cannot be negative")
|
|
|
|
| 430 |
|
| 431 |
Args:
|
| 432 |
outdoor_temp: Outdoor air temperature in °C
|
| 433 |
+
solar_irradiance: Solar irradiance on surface in W/m²
|
| 434 |
surface_absorptivity: Surface absorptivity (0-1)
|
| 435 |
+
surface_resistance: Surface resistance in m²·K/W
|
| 436 |
|
| 437 |
Returns:
|
| 438 |
Sol-air temperature in °C
|
| 439 |
"""
|
| 440 |
self.validate_inputs(outdoor_temp)
|
| 441 |
if solar_irradiance < 0:
|
| 442 |
+
raise ValueError(f"Solar irradiance {solar_irradiance} W/m² cannot be negative")
|
| 443 |
if not 0 <= surface_absorptivity <= 1:
|
| 444 |
raise ValueError(f"Surface absorptivity {surface_absorptivity} must be between 0 and 1")
|
| 445 |
if surface_resistance < 0:
|
| 446 |
+
raise ValueError(f"Surface resistance {surface_resistance} m²·K/W cannot be negative")
|
| 447 |
|
| 448 |
h_ext = 1 / surface_resistance # External convective coefficient
|
| 449 |
delta_t_rad = surface_absorptivity * solar_irradiance / h_ext
|
|
|
|
| 455 |
Calculate solar heat gain through a surface.
|
| 456 |
|
| 457 |
Args:
|
| 458 |
+
irradiance: Solar irradiance on surface in W/m²
|
| 459 |
+
area: Surface area in m²
|
| 460 |
shgc: Solar heat gain coefficient (0-1)
|
| 461 |
shading_coefficient: Shading coefficient (0-1)
|
| 462 |
|
|
|
|
| 465 |
"""
|
| 466 |
self.validate_inputs(0, area)
|
| 467 |
if irradiance < 0:
|
| 468 |
+
raise ValueError(f"Irradiance {irradiance} W/m² cannot be negative")
|
| 469 |
if not 0 <= shgc <= 1:
|
| 470 |
raise ValueError(f"SHGC {shgc} must be between 0 and 1")
|
| 471 |
if not 0 <= shading_coefficient <= 1:
|
|
|
|
| 495 |
print(f"Solar Azimuth: {azimuth:.2f}°")
|
| 496 |
|
| 497 |
# Example heat transfer calculation
|
| 498 |
+
u_value = 0.5 # W/(m²·K)
|
| 499 |
+
area = 20.0 # m²
|
| 500 |
delta_t = 10.0 # °C
|
| 501 |
conduction = heat_transfer_calculator.conduction_heat_transfer(u_value, area, delta_t)
|
| 502 |
print(f"Conduction Heat Transfer: {conduction:.2f} W")
|