4
4
5
5
import pydantic .v1 as pd
6
6
7
+ from typing import Union
7
8
from tidy3d .components .tcad .boundary .abstract import HeatChargeBC
8
9
from tidy3d .constants import HEAT_FLUX , HEAT_TRANSFER_COEFF , KELVIN
9
10
@@ -39,6 +40,100 @@ class HeatFluxBC(HeatChargeBC):
39
40
units = HEAT_FLUX ,
40
41
)
41
42
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
42
137
43
138
class ConvectionBC (HeatChargeBC ):
44
139
"""Convective thermal boundary conditions.
@@ -55,8 +150,12 @@ class ConvectionBC(HeatChargeBC):
55
150
units = KELVIN ,
56
151
)
57
152
58
- transfer_coeff : pd .NonNegativeFloat = pd .Field (
153
+ transfer_coeff : Union [ pd .NonNegativeFloat , NaturalConvectionVerticalSpec ] = pd .Field (
59
154
title = "Heat Transfer Coefficient" ,
60
155
description = f"Heat flux value in units of { HEAT_TRANSFER_COEFF } ." ,
61
156
units = HEAT_TRANSFER_COEFF ,
62
157
)
158
+
159
+ #TODO Maybe I should find a better place for these lines.
160
+ NaturalConvectionVerticalSpec .update_forward_refs ()
161
+ ConvectionBC .update_forward_refs ()
0 commit comments