Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ breaking changes to the API or the command-line interface; patch releases

### Added

- Deck reader: under `--fasthenry-compat`, a diagonal `contact trace` is
accepted (issue #157) and refined as its bounding box padded by `3w/2`,
with cells `(w/2)·scale_factor^min(|tan θ|, |cot θ|)`, and a
line-numbered warning that this approximates FastHenry's staircase
refinement. Native mode still rejects it.
- Deck reader: `relx=` / `rely=` / `relz=` on a corner-point `G` statement
(issue #146), the documented offset (User's Guide §1.3.9), in every mode.
It is added to every node-reference, hole and contact coordinate on the
Expand Down
20 changes: 18 additions & 2 deletions docs/fasthenry-compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ records how each documented field maps.
| `hole user1 (…)` … `hole user7 (…)` | Not supported, permanent | Issue #99. Rejected by name on the statement's own line, and the rejection is final rather than deferred — see the decision below. The error names the alternatives: the declarative shapes above, and `fasterhenry::plane::GroundPlane::mesh` + `fasterhenry::plane::Hole::Point` for a shape none of them describe. |
| `contact point (x, y, z, xcell, ycell)`, `contact line (x0, y0, z0, x1, y1, z1, xcell, ycell)` | Supported, differs | Issue #100. Every cell holding the point, or crossed by the line, is no larger than `xcell` × `ycell` — the pair measured in the plane's own coordinate system, `xcell` along `p1 → p2` (the decision below; this is the clause the public memo states that convention for outright), while the point's or line's own coordinates are global. Both map onto one `fasterhenry::plane::ContactRegion`: the locus's bounding box padded by half a requested cell on every side, cut into the fewest cells no larger than that cell — so a point is exactly one `xcell × ycell` cell centred on it, and a zero-length line is that point. Outside it the mesh grades back at ratio 2, the reader's `contact rect` default (neither shape documents a decay). A requested cell at or above the plane's background cell is already met and is clamped there rather than coarsening the mesh; a point or line met on both axes adds nothing. Both ends are checked against the plane's slab and footprint. **The difference**: a diagonal line refines its whole padded bounding box, because this engine's mesh is a tensor product — a refined band on one axis spans the plane on the other, so any refinement covering the line (a chain of rectangles included) has the same bands. That costs about `(Lx/xcell)·(Ly/ycell)` fine cells where a mesh following the diagonal would need about `Lx/xcell + Ly/ycell`; an axis-aligned line costs nothing extra. |
| `contact trace (x0, y0, z0, x1, y1, z1, trace_width, scale_factor)` along x or y | Supported | Issue #110. Refines the plane finely across the trace's projection, not along it. Source: the public memo *Nonuniformly Discretized Reference Planes in FastHenry 3.0* (M. Kamon, 10 October 1996, section "Grouped contact utilities"), whose worked example expands an x-directed trace of width `w` and length `L` into five `contact line`s — at the trace and at `±w/2` with cells `(L, w/2)`, and at `±3w/2` with cells `(L, w)` — and which states that `scale_factor` has no effect on a trace parallel to x or y. This reader performs exactly that expansion (axes swapped for a trace along y), each line mapping as in the `contact line` row above; writing the five lines out by hand gives the same mesh, which `contact_trace_along_x_is_the_documented_five_lines` in `inp.rs` asserts. `scale_factor` is checked to be positive and otherwise unused. The trace's own ends are checked against the plane's slab and footprint on the statement's line; the side lines are clipped to the plane (and dropped where they miss it), so a trace along the plane's edge is accepted. A zero-length trace has no direction and is a line-numbered error naming `contact point`. The clause carries no `x…`/`y…` pair of its own — one `trace_width`, and a direction read from its own global ends — and its expansion is symmetric in the two axes, so the plane-coordinate decision below does not touch it: rotating the plane rotates the trace with it (issue #118). |
| `contact trace (…)` not parallel to x or y | Not supported, permanent | Issue #110. Rejected by name on the statement's own line, as a decision rather than deferred work — see "Decision: a diagonal `contact trace` is rejected" below. The error names `contact line (x0, y0, z0, x1, y1, z1, xcell, ycell)`, which states the cell size outright. |
| `contact trace (…)` not parallel to x or y | Native: not supported, permanent. `--fasthenry-compat`: supported, approximated | Issue #110 (native), issue #157 (compat). Under compat the trace is refined as its bounding box padded by `3w/2` on every side — a `contact rect` over it with cells `(w/2)·scale_factor^min(|tan θ|, \|cot θ\|)` on both axes, θ measured in the plane's own frame so 30° and 60° mirror each other — with a line-numbered warning that this approximates FastHenry's staircase refinement (see the decision below). Natively: rejected by name on the statement's own line, as a decision rather than deferred work — see "Decision: a diagonal `contact trace` is rejected" below. The error names `contact line (x0, y0, z0, x1, y1, z1, xcell, ycell)`, which states the cell size outright. |
| `contact circle (…)` | Not supported, permanent | Issue #109. Rejected by name on the statement's own line — and, like the diagonal `contact trace` row above, this is not deferred work: the public description of the `contact` family names the simple refinement utilities `point`, `line`, `rect` and `decay_rect`, the contact-*area* utility `equiv_rect`, the grouped `connection` and `trace` built on them, and the `initial_grid`/`initial_mesh_grid` pair — no disc among them. `circle` is a **hole** shape (`hole circle (x, y, z, r)`), so there is no argument list to pin and nothing in a deck to read — see the decision below. The geometry is not what is missing: on this tensor-product mesh the whole of what a disc could mean is `contact decay_rect` over its bounding square, and the error names that. |
| `contact initial_grid (n1, n2)` | Supported | Issue #113, which pinned the convention #101 left open: `n1` cells along `p1 → p2` and `n2` along `p2 → p3` — the same pair `seg1`/`seg2` set, as the clause's own public description states ("`seg1=10 seg2=12` could be replaced with `file=NONE contact initial_grid (10,12)`"). See the decision below for the evidence, including why the description's word *rows* does not overturn it. The counts are cells, not grid lines. Because the two clauses are one statement, a plane giving both `contact initial_grid` and `seg1`/`seg2` (in either order), or two initial grids, is a line-numbered error rather than a race between them. `file=NONE`, which the public example pairs with the clause, is accepted as the no-op it is (issue #122 — see its own row above), so the documented line reads as written; the token says there is no discretization hierarchy file, which is the only case this reader has. |
| `contact initial_mesh_grid (n1, n2)` | Supported, differs | Issue #113. That same initial grid, plus the documented checkerboard: "every cell that has an even value for both of its indices where the numbering is from the top left" — so, with the cells numbered from 1 at the plane's own origin (its `p1` corner) along each axis, every cell whose two indices are **both even**. An axis of one cell has no even index and so no hole. The difference is what each hole *is*: a `Hole::Rect` over the holed cell's own rectangle rather than a `Hole::Point` at its centre. On the initial grid alone the two are the same cut; the grid is *initial*, though, and a later `contact` clause may refine that region — the documented hole is the square ("no conductor will be defined in that square region"), not whichever smaller cell a refinement leaves under the centre. Numbering from `p1` is what fixes the checkerboard's phase: for an odd count either end selects the same cells, but for an even count the two differ by one cell, and `p1` is the origin of the plane coordinate system the same description defines (and the corner its own uniform-plane figure draws at the top left). |
Expand Down Expand Up @@ -330,7 +330,23 @@ the disc misses.
two-line parser arm over the mapping above, with the padding rule
`contact point` already uses. Nothing about the plane model would change.

### Decision: a diagonal `contact trace` is rejected (issue #110)
### Decision: a diagonal `contact trace` is rejected natively, approximated under compat (issue #110, #157)

*Native mode* keeps the rejection described below: the public description
does not determine the cell size, so the native reader will not guess.
*`--fasthenry-compat`* (issue #157) instead accepts the clause and refines
the trace's bounding box, padded by `3w/2` on every side, to cells
`(w/2)·s^min(|tan θ|, |cot θ|)` on both axes (`s` = `scale_factor`, θ from
`p1 → p2` in the plane's frame), as one `contact rect`. Black-box runs
against self-authored decks show this lands within a few percent of
FastHenry's own staircase refinement (about 0.1-0.4% in L and 0.3-2% in R at
`s = 1`), against about 5% without any refinement. The `min()` deliberately
keeps 30° and 60° mirror-symmetric rather than copying FastHenry's behaviour
past 45°, and the cell is capped at half the box's narrower width. A
line-numbered warning says the refinement approximates FastHenry's staircase.
The word "permanent" in this section's native rationale applies to native
mode only.


A `contact trace` parallel to x or y is supported (its row above): the
public memo *Nonuniformly Discretized Reference Planes in FastHenry 3.0*
Expand Down
Loading
Loading