Skip to content

Commit 18d3319

Browse files
committed
fix(FXC-5154): add function to compute min radius
1 parent 077cf70 commit 18d3319

1 file changed

Lines changed: 43 additions & 14 deletions

File tree

tidy3d/components/tcad/simulation/heat_charge.py

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,45 @@
125125
# define some limits for transient heat simulations
126126
TRANSIENT_HEAT_MAX_STEPS = 1000
127127

128-
# OpenCASCADE minimum tolerance for cylinder radii
129-
OPENCASCADE_CYLINDER_RADIUS_TOL = 1e-6
128+
# Minimum tolerance for cylinder radii
129+
CYLINDER_RADIUS_TOL = 1e-6
130130
# Minimum radius as fraction of the larger radius (for tapered cylinders)
131131
MIN_CYLINDER_RADIUS_FRACTION = 0.01
132132

133133

134+
def _get_cylinder_radii_with_meshing_tol(geometry: Cylinder) -> tuple[float, float]:
135+
"""Get cylinder radii clamped to the minimum meshing tolerance.
136+
137+
OpenCASCADE has a minimum tolerance for radii; this function clamps
138+
small or negative values to a small positive value to ensure valid
139+
geometry that can be meshed. The minimum is set relative to the larger
140+
radius to ensure meshability while still creating a reasonably sharp
141+
tip for tapered cylinders.
142+
143+
Parameters
144+
----------
145+
geometry : Cylinder
146+
The cylinder geometry to get radii from.
147+
148+
Returns
149+
-------
150+
tuple[float, float]
151+
``(r1, r2)`` -- bottom and top radii, clamped to the minimum allowed radius.
152+
"""
153+
r1 = geometry.radius_bottom
154+
r2 = geometry.radius_top
155+
156+
min_radius = max(
157+
CYLINDER_RADIUS_TOL,
158+
MIN_CYLINDER_RADIUS_FRACTION * max(abs(r1), abs(r2)),
159+
)
160+
161+
r1 = max(r1, min_radius)
162+
r2 = max(r2, min_radius)
163+
164+
return r1, r2
165+
166+
134167
class TCADAnalysisTypes(str, Enum):
135168
"""Enumeration of the types of simulations currently supported"""
136169

@@ -376,31 +409,27 @@ def _warn_small_cylinder_radius(cls, val: tuple[Structure, ...]) -> tuple[Struct
376409
r_top = base_geometry.radius_top
377410
is_tapered = not np.isclose(r_bottom, r_top)
378411

379-
# Compute minimum allowed radius (matches backend heat_mesh.py logic)
380-
min_radius = max(
381-
OPENCASCADE_CYLINDER_RADIUS_TOL,
382-
MIN_CYLINDER_RADIUS_FRACTION * max(abs(r_bottom), abs(r_top)),
383-
)
412+
r1, r2 = _get_cylinder_radii_with_meshing_tol(base_geometry)
384413

385-
# Warn if radii are below minimum
414+
# Warn if radii were clamped
386415
if is_tapered:
387-
if r_bottom < min_radius:
416+
if r1 > r_bottom:
388417
log.warning(
389418
f"Cylinder 'radius_bottom' ({r_bottom:.3e}) is below the minimum "
390-
f"radius for meshing ({min_radius:.3e}). The sidewall angle may be "
419+
f"radius for meshing ({r1:.3e}). The sidewall angle may be "
391420
f"too steep. Will be clamped to minimum radius or mesh size, whichever is larger."
392421
)
393-
if r_top < min_radius:
422+
if r2 > r_top:
394423
log.warning(
395424
f"Cylinder 'radius_top' ({r_top:.3e}) is below the minimum "
396-
f"radius for meshing ({min_radius:.3e}). The sidewall angle may be "
425+
f"radius for meshing ({r2:.3e}). The sidewall angle may be "
397426
f"too steep. Will be clamped to minimum radius or mesh size, whichever is larger."
398427
)
399428
else:
400-
if r_bottom < min_radius:
429+
if r1 > r_bottom:
401430
log.warning(
402431
f"Cylinder 'radius' ({r_bottom:.3e}) is below the minimum "
403-
f"radius for meshing ({min_radius:.3e}). "
432+
f"radius for meshing ({r1:.3e}). "
404433
f"Will be clamped to minimum radius or mesh size, whichever is larger."
405434
)
406435
return val

0 commit comments

Comments
 (0)