Skip to content

Commit 145793e

Browse files
committed
FEAT: Add natural convection BC
1 parent 38ccd41 commit 145793e

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

tidy3d/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
CaugheyThomasMobility,
6969
ConstantMobilityModel,
7070
ConvectionBC,
71+
NaturalConvectionVerticalSpec,
7172
CurrentBC,
7273
HeatFluxBC,
7374
HeatFromElectricSource,
@@ -405,6 +406,7 @@ def set_logging_level(level: str) -> None:
405406
Transformed.update_forward_refs()
406407
ClipOperation.update_forward_refs()
407408
GeometryGroup.update_forward_refs()
409+
ConvectionBC.update_forward_refs()
408410

409411
__all__ = [
410412
"C_0",
@@ -713,4 +715,5 @@ def set_logging_level(level: str) -> None:
713715
"set_logging_console",
714716
"set_logging_file",
715717
"wavelengths",
718+
"NaturalConvectionVerticalSpec",
716719
]

tidy3d/components/tcad/boundary/heat.py

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import pydantic.v1 as pd
66

7+
from typing import Union
78
from tidy3d.components.tcad.boundary.abstract import HeatChargeBC
89
from tidy3d.constants import HEAT_FLUX, HEAT_TRANSFER_COEFF, KELVIN
910

@@ -39,6 +40,100 @@ class HeatFluxBC(HeatChargeBC):
3940
units=HEAT_FLUX,
4041
)
4142

43+
#TODO Should I adapt to Tidy3D units (e.g. micrometers), or keep the original ones?
44+
THERMAL_CONDUCTIVITY_UNITS = "W/(m*K)"
45+
DYNAMIC_VISCOSITY_UNITS = "Pa*s"
46+
SPECIFIC_HEAT_UNITS = "J/(kg*K)"
47+
DENSITY_UNITS = "kg/m**3"
48+
THERMAL_EXPANSIVITY_UNITS = "1/K"
49+
LENGTH_UNITS = "m"
50+
ACCELERATION_UNITS = "m/s**2"
51+
52+
class NaturalConvectionVerticalSpec(HeatChargeBC):
53+
"""
54+
Specification for natural convection from a vertical plate.
55+
56+
This class calculates the heat transfer coefficient (h) based on fluid
57+
properties and an expected temperature difference, then provides these
58+
values as 'base' and 'exponent' for a generalized heat flux equation
59+
q = base * (T_surf - T_fluid)^exponent.
60+
"""
61+
# --- Input Parameters ---
62+
fluid_k: pd.NonNegativeFloat = pd.Field(
63+
title="Fluid Thermal Conductivity",
64+
description="Thermal conductivity (k) of the fluid.",
65+
units=THERMAL_CONDUCTIVITY_UNITS,
66+
)
67+
fluid_mu: pd.NonNegativeFloat = pd.Field(
68+
title="Fluid Dynamic Viscosity",
69+
description="Dynamic viscosity (μ) of the fluid.",
70+
units=DYNAMIC_VISCOSITY_UNITS,
71+
)
72+
fluid_Cp: pd.NonNegativeFloat = pd.Field(
73+
title="Fluid Specific Heat",
74+
description="Specific heat capacity (Cp) of the fluid at constant pressure.",
75+
units=SPECIFIC_HEAT_UNITS,
76+
)
77+
fluid_rho: pd.NonNegativeFloat = pd.Field(
78+
title="Fluid Density",
79+
description="Density (ρ) of the fluid.",
80+
units=DENSITY_UNITS,
81+
)
82+
fluid_beta: pd.NonNegativeFloat = pd.Field(
83+
title="Fluid Thermal Expansivity",
84+
description="Thermal expansion coefficient (β) of the fluid.",
85+
units=THERMAL_EXPANSIVITY_UNITS,
86+
)
87+
plate_L: pd.NonNegativeFloat = pd.Field(
88+
title="Plate Characteristic Length",
89+
description="Characteristic length (L), defined as the height of the vertical plate.",
90+
units=LENGTH_UNITS,
91+
)
92+
93+
gravity: pd.NonNegativeFloat = pd.Field(
94+
default=9.80665,
95+
title="Gravitational Acceleration",
96+
description="Gravitational acceleration (g).",
97+
units=ACCELERATION_UNITS,
98+
)
99+
100+
def _compute_parameters(self):
101+
102+
# Calculate the Rayleigh Number (Ra_L)
103+
rayleigh_numerator_notemp = (
104+
self.gravity
105+
* self.fluid_beta
106+
* self.fluid_rho ** 2
107+
* self.fluid_Cp
108+
* self.plate_L ** 3
109+
)
110+
rayleigh_denominator = self.fluid_mu * self.fluid_k
111+
Ra_L = rayleigh_numerator_notemp / rayleigh_denominator
112+
113+
# Calculate the denominator term from the Nusselt number correlation
114+
# This term is related to the Prandtl Number (Pr = mu * Cp / k)
115+
pr_term_inner_num = 0.492 * self.fluid_k
116+
pr_term_inner_den = self.fluid_mu * self.fluid_Cp
117+
118+
pr_term_inner = pr_term_inner_num / pr_term_inner_den
119+
pr_denominator = (1 + pr_term_inner ** (9 / 16)) ** (4 / 9)
120+
121+
# Select formula based on flow regime (determined by Ra_L)
122+
if Ra_L <= 1e9:
123+
# Laminar Flow
124+
h_factor_linear = 0.68
125+
h_factor_non_linear = (0.670 * Ra_L ** (1 / 6)) / pr_denominator
126+
elif 1e9 < Ra_L <= 1e13:
127+
# Turbulent Flow
128+
h_factor_linear = 0.825
129+
h_factor_non_linear = (0.387 * Ra_L ** (1 / 6)) / pr_denominator
130+
else:
131+
raise ValueError(f"Ra_l={Ra_L} should be smaller than 1e13 for NaturalConvectionVerticalSpec")
132+
133+
h = (self.fluid_k / self.plate_L) * h_factor_linear
134+
h_nonlinear = (self.fluid_k / self.plate_L) * h_factor_non_linear
135+
exponent = 1 + 1/6
136+
return h, h_nonlinear, exponent
42137

43138
class ConvectionBC(HeatChargeBC):
44139
"""Convective thermal boundary conditions.
@@ -55,8 +150,12 @@ class ConvectionBC(HeatChargeBC):
55150
units=KELVIN,
56151
)
57152

58-
transfer_coeff: pd.NonNegativeFloat = pd.Field(
153+
transfer_coeff: Union[pd.NonNegativeFloat, NaturalConvectionVerticalSpec] = pd.Field(
59154
title="Heat Transfer Coefficient",
60155
description=f"Heat flux value in units of {HEAT_TRANSFER_COEFF}.",
61156
units=HEAT_TRANSFER_COEFF,
62157
)
158+
159+
#TODO Maybe I should find a better place for these lines.
160+
NaturalConvectionVerticalSpec.update_forward_refs()
161+
ConvectionBC.update_forward_refs()

tidy3d/components/tcad/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from tidy3d.components.tcad.bandgap import SlotboomBandGapNarrowing
66
from tidy3d.components.tcad.boundary.charge import CurrentBC, InsulatingBC, VoltageBC
7-
from tidy3d.components.tcad.boundary.heat import ConvectionBC, HeatFluxBC, TemperatureBC
7+
from tidy3d.components.tcad.boundary.heat import ConvectionBC, HeatFluxBC, TemperatureBC, NaturalConvectionVerticalSpec
88
from tidy3d.components.tcad.generation_recombination import (
99
AugerRecombination,
1010
RadiativeRecombination,

0 commit comments

Comments
 (0)