Geometry options¶
StackOptions collects the geometry features that cost time. All are on by default, the most accurate setting;
StackOptions.fast() turns off those a quick look at a device does not need. The same device, built both ways:
import fdtdx
import gdsfactory as gf
import bifrost as bf
from gdsfactory.technology import LayerLevel, LayerStack
gf.gpdk.PDK.activate()
component = gf.components.straight(length=5) # a 5 um long, 500 nm wide waveguide with ports o1 and o2
layer_stack = LayerStack(
layers={"core": LayerLevel(layer=gf.gpdk.LAYER.WG, zmin=0.0, thickness=0.22, material="core", mesh_order=1)}
)
materials = {"core": fdtdx.Material(permittivity=3.48**2), "clad": fdtdx.Material(permittivity=1.444**2)}
def build(options: bf.StackOptions) -> bf.StackDevice:
return bf.StackDevice.from_layer_stack(
component, layer_stack, materials, background="clad", zrange_layers=["core"],
extend_ports=(("o1", 1.0), ("o2", 1.0)), boundary_offset=(0, 0, 1.5, -1.5, 1.5, -1.5),
options=options, name="stack",
)
accurate = build(bf.StackOptions()) # every accuracy feature on: the default
quick = build(bf.StackOptions.fast()) # for a quick look: no corner model, no Yee staggering, no diagnostics
for name, device in (("default", accurate), ("fast", quick)):
o = device.options
print(f"{name:8} averaging={o.averaging} yee_staggered={o.yee_staggered} corner_lines={o.corner_lines} diagnostics={o.diagnostics}")
Output:
default averaging=subpixel yee_staggered=True corner_lines=2 diagnostics=True
fast averaging=inverse yee_staggered=False corner_lines=0 diagnostics=False
Pass options= to from_layer_stack, or individual fields such as corner_lines=0, but not both. device.options
returns a built device's options.
What each option buys¶
| Option (default) | What it buys |
|---|---|
corner_lines=2 (0: off) |
exact fill at polygon corners and edge crossings: corner voxels off by up to 0.25 (convex) and 0.31 (rotated polygons) without, 1e-6 with |
averaging="subpixel" ("inverse") |
Kottke averaging (the diagonal of the averaged tensor): second-order accurate at interfaces along the grid; first order at oblique ones (see below) |
averaging="subpixel_full" (opt-in) |
complete tensors: anisotropic materials (full tensors), Kottke's anisotropic laminate at planar interfaces in every entry, a junction closure at corners (see below) |
subpixel_normal="voxel" ("gradient") |
the normal of each voxel's own model: exact at slanted walls (0.01 deg), where finite differences of the mean eps are 8-33 deg off |
yee_staggered=True |
each E component's own Yee position (first-order error without) |
xy_subsamples=1 |
s > 1 refines tips and dense curves, at about s² the cost |
derived_shapes="exact" ("composite") |
no slivers where edges of a derived level's layers coincide (0.88 of a voxel before) |
diagnostics=True |
warnings about unresolved parts and gaps |
The corner model and the full-tensor averaging are the expensive options; the rest are cheap. Measured costs: Validation and benchmarks.