@vessel-dsp/compiler 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -2
- package/dist/bake.d.ts +38 -0
- package/dist/bake.d.ts.map +1 -0
- package/dist/bake.js +101 -0
- package/dist/bake.js.map +1 -0
- package/dist/bbd-clock.d.ts +171 -0
- package/dist/bbd-clock.d.ts.map +1 -0
- package/dist/bbd-clock.js +1750 -0
- package/dist/bbd-clock.js.map +1 -0
- package/dist/block-row.d.ts +51 -0
- package/dist/block-row.d.ts.map +1 -0
- package/dist/block-row.js +17 -0
- package/dist/block-row.js.map +1 -0
- package/dist/bypass.d.ts +3 -0
- package/dist/bypass.d.ts.map +1 -0
- package/dist/bypass.js +228 -0
- package/dist/bypass.js.map +1 -0
- package/dist/compile.d.ts +24 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +348 -0
- package/dist/compile.js.map +1 -0
- package/dist/converter-scale.d.ts +14 -0
- package/dist/converter-scale.d.ts.map +1 -0
- package/dist/converter-scale.js +133 -0
- package/dist/converter-scale.js.map +1 -0
- package/dist/couple.d.ts +28 -0
- package/dist/couple.d.ts.map +1 -0
- package/dist/couple.js +567 -0
- package/dist/couple.js.map +1 -0
- package/dist/dangling-active-terminal.d.ts +47 -0
- package/dist/dangling-active-terminal.d.ts.map +1 -0
- package/dist/dangling-active-terminal.js +542 -0
- package/dist/dangling-active-terminal.js.map +1 -0
- package/dist/declared-program.d.ts +23 -0
- package/dist/declared-program.d.ts.map +1 -0
- package/dist/declared-program.js +387 -0
- package/dist/declared-program.js.map +1 -0
- package/dist/denomination.d.ts +48 -0
- package/dist/denomination.d.ts.map +1 -0
- package/dist/denomination.js +27 -0
- package/dist/denomination.js.map +1 -0
- package/dist/device-laws.d.ts +237 -0
- package/dist/device-laws.d.ts.map +1 -0
- package/dist/device-laws.js +3513 -0
- package/dist/device-laws.js.map +1 -0
- package/dist/diagnostics.d.ts +13 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +19 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/emit.d.ts +8 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +43 -0
- package/dist/emit.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/firmware-class.d.ts +69 -0
- package/dist/firmware-class.d.ts.map +1 -0
- package/dist/firmware-class.js +20 -0
- package/dist/firmware-class.js.map +1 -0
- package/dist/fixtures/circuits.d.ts +1742 -0
- package/dist/fixtures/circuits.d.ts.map +1 -0
- package/dist/fixtures/circuits.js +13896 -0
- package/dist/fixtures/circuits.js.map +1 -0
- package/dist/fixtures/expected.d.ts +261 -0
- package/dist/fixtures/expected.d.ts.map +1 -0
- package/dist/fixtures/expected.js +315 -0
- package/dist/fixtures/expected.js.map +1 -0
- package/dist/fixtures/index.d.ts +4 -0
- package/dist/fixtures/index.d.ts.map +1 -0
- package/dist/fixtures/index.js +8 -0
- package/dist/fixtures/index.js.map +1 -0
- package/dist/fixtures/registry.d.ts +52 -0
- package/dist/fixtures/registry.d.ts.map +1 -0
- package/dist/fixtures/registry.js +341 -0
- package/dist/fixtures/registry.js.map +1 -0
- package/dist/generic-tube-fit.d.ts +12 -0
- package/dist/generic-tube-fit.d.ts.map +1 -0
- package/dist/generic-tube-fit.js +45 -0
- package/dist/generic-tube-fit.js.map +1 -0
- package/dist/grounded-clock-supply.d.ts +13 -0
- package/dist/grounded-clock-supply.d.ts.map +1 -0
- package/dist/grounded-clock-supply.js +45 -0
- package/dist/grounded-clock-supply.js.map +1 -0
- package/dist/identify.d.ts +50 -0
- package/dist/identify.d.ts.map +1 -0
- package/dist/identify.js +319 -0
- package/dist/identify.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/inert-controls.d.ts +15 -0
- package/dist/inert-controls.d.ts.map +1 -0
- package/dist/inert-controls.js +266 -0
- package/dist/inert-controls.js.map +1 -0
- package/dist/latch-seed.d.ts +53 -0
- package/dist/latch-seed.d.ts.map +1 -0
- package/dist/latch-seed.js +257 -0
- package/dist/latch-seed.js.map +1 -0
- package/dist/link.d.ts +7 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +270 -0
- package/dist/link.js.map +1 -0
- package/dist/lower.d.ts +79 -0
- package/dist/lower.d.ts.map +1 -0
- package/dist/lower.js +1855 -0
- package/dist/lower.js.map +1 -0
- package/dist/netlist.d.ts +79 -0
- package/dist/netlist.d.ts.map +1 -0
- package/dist/netlist.js +4746 -0
- package/dist/netlist.js.map +1 -0
- package/dist/non-executable-clock-drivers.d.ts +8 -0
- package/dist/non-executable-clock-drivers.d.ts.map +1 -0
- package/dist/non-executable-clock-drivers.js +33 -0
- package/dist/non-executable-clock-drivers.js.map +1 -0
- package/dist/open-category.d.ts +98 -0
- package/dist/open-category.d.ts.map +1 -0
- package/dist/open-category.js +111 -0
- package/dist/open-category.js.map +1 -0
- package/dist/over-driven-node.d.ts +33 -0
- package/dist/over-driven-node.d.ts.map +1 -0
- package/dist/over-driven-node.js +188 -0
- package/dist/over-driven-node.js.map +1 -0
- package/dist/part-catalog.d.ts +15 -0
- package/dist/part-catalog.d.ts.map +1 -0
- package/dist/part-catalog.js +6712 -0
- package/dist/part-catalog.js.map +1 -0
- package/dist/part-number.d.ts +32 -0
- package/dist/part-number.d.ts.map +1 -0
- package/dist/part-number.js +80 -0
- package/dist/part-number.js.map +1 -0
- package/dist/partition.d.ts +7 -0
- package/dist/partition.d.ts.map +1 -0
- package/dist/partition.js +242 -0
- package/dist/partition.js.map +1 -0
- package/dist/port-full-scale.d.ts +70 -0
- package/dist/port-full-scale.d.ts.map +1 -0
- package/dist/port-full-scale.js +235 -0
- package/dist/port-full-scale.js.map +1 -0
- package/dist/pot-orientation.d.ts +114 -0
- package/dist/pot-orientation.d.ts.map +1 -0
- package/dist/pot-orientation.js +551 -0
- package/dist/pot-orientation.js.map +1 -0
- package/dist/power-domain-control.d.ts +40 -0
- package/dist/power-domain-control.d.ts.map +1 -0
- package/dist/power-domain-control.js +142 -0
- package/dist/power-domain-control.js.map +1 -0
- package/dist/proxy-declaration.d.ts +121 -0
- package/dist/proxy-declaration.d.ts.map +1 -0
- package/dist/proxy-declaration.js +50 -0
- package/dist/proxy-declaration.js.map +1 -0
- package/dist/registry.d.ts +323 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +192 -0
- package/dist/registry.js.map +1 -0
- package/dist/sparse-schedule.d.ts +65 -0
- package/dist/sparse-schedule.d.ts.map +1 -0
- package/dist/sparse-schedule.js +421 -0
- package/dist/sparse-schedule.js.map +1 -0
- package/dist/speaker-load.d.ts +38 -0
- package/dist/speaker-load.d.ts.map +1 -0
- package/dist/speaker-load.js +97 -0
- package/dist/speaker-load.js.map +1 -0
- package/dist/stage-coverage.d.ts +21 -0
- package/dist/stage-coverage.d.ts.map +1 -0
- package/dist/stage-coverage.js +124 -0
- package/dist/stage-coverage.js.map +1 -0
- package/dist/stamp-partition.d.ts +314 -0
- package/dist/stamp-partition.d.ts.map +1 -0
- package/dist/stamp-partition.js +472 -0
- package/dist/stamp-partition.js.map +1 -0
- package/dist/supply-reference.d.ts +19 -0
- package/dist/supply-reference.d.ts.map +1 -0
- package/dist/supply-reference.js +66 -0
- package/dist/supply-reference.js.map +1 -0
- package/dist/supply-short.d.ts +32 -0
- package/dist/supply-short.d.ts.map +1 -0
- package/dist/supply-short.js +118 -0
- package/dist/supply-short.js.map +1 -0
- package/dist/supply-stamps.d.ts +51 -0
- package/dist/supply-stamps.d.ts.map +1 -0
- package/dist/supply-stamps.js +363 -0
- package/dist/supply-stamps.js.map +1 -0
- package/dist/terminal-role.d.ts +109 -0
- package/dist/terminal-role.d.ts.map +1 -0
- package/dist/terminal-role.js +46 -0
- package/dist/terminal-role.js.map +1 -0
- package/dist/terminal-roles.d.ts +59 -0
- package/dist/terminal-roles.d.ts.map +1 -0
- package/dist/terminal-roles.js +92 -0
- package/dist/terminal-roles.js.map +1 -0
- package/dist/transformer.d.ts +181 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/transformer.js +476 -0
- package/dist/transformer.js.map +1 -0
- package/dist/types.d.ts +3157 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/unbounded-operating-point.d.ts +35 -0
- package/dist/unbounded-operating-point.d.ts.map +1 -0
- package/dist/unbounded-operating-point.js +181 -0
- package/dist/unbounded-operating-point.js.map +1 -0
- package/dist/unexecuted-region.d.ts +3 -0
- package/dist/unexecuted-region.d.ts.map +1 -0
- package/dist/unexecuted-region.js +122 -0
- package/dist/unexecuted-region.js.map +1 -0
- package/dist/unimplemented-control-role.d.ts +3 -0
- package/dist/unimplemented-control-role.d.ts.map +1 -0
- package/dist/unimplemented-control-role.js +61 -0
- package/dist/unimplemented-control-role.js.map +1 -0
- package/dist/unreachable-output.d.ts +3 -0
- package/dist/unreachable-output.d.ts.map +1 -0
- package/dist/unreachable-output.js +97 -0
- package/dist/unreachable-output.js.map +1 -0
- package/dist/unreadable-terminal-role.d.ts +67 -0
- package/dist/unreadable-terminal-role.d.ts.map +1 -0
- package/dist/unreadable-terminal-role.js +409 -0
- package/dist/unreadable-terminal-role.js.map +1 -0
- package/dist/unverified-pinout.d.ts +27 -0
- package/dist/unverified-pinout.d.ts.map +1 -0
- package/dist/unverified-pinout.js +121 -0
- package/dist/unverified-pinout.js.map +1 -0
- package/package.json +75 -5
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
// Transformer winding resolution, split out of `lower.ts` (R7, 2026-09-01).
|
|
2
|
+
//
|
|
3
|
+
// This is winding work, not MNA work: the stamps a transformer contributes are two lines in
|
|
4
|
+
// `lowerRegion`, and everything here exists to answer which declared coil drives, which is
|
|
5
|
+
// coupled, and which end is unpaired.
|
|
6
|
+
//
|
|
7
|
+
// Until 2026-09-03 it also had to answer *which terminals form a coil*, from a 110-entry table
|
|
8
|
+
// keyed on folded terminal spellings that grew one packet at a time. `@vessel-dsp/core@0.6.35`
|
|
9
|
+
// makes the coil grouping a declaration (`windings`) and the corpus declares it, so the table is
|
|
10
|
+
// gone and `transformerWindings` reads. R1 in
|
|
11
|
+
// `thoughts/shared/plans/archive/2026-08-31-v2-complexity-reduction-plan.md` is the plan this closes.
|
|
12
|
+
import { LoweringError } from "./errors.js";
|
|
13
|
+
import { GROUND } from "./types.js";
|
|
14
|
+
/**
|
|
15
|
+
* How many `(device, terminal)` references touch each node across the whole netlist.
|
|
16
|
+
*
|
|
17
|
+
* Existence evidence, not a corpus-wide cost: `transformerWindings` is the only reader, and
|
|
18
|
+
* only when its own terminal grouping turns up a winding with a single, unpaired end. A node
|
|
19
|
+
* this stage never asks about -- ground, or any node two ordinary components share -- costs
|
|
20
|
+
* nothing extra to have counted.
|
|
21
|
+
*/
|
|
22
|
+
export function nodeOccurrenceCounts(devices) {
|
|
23
|
+
const counts = new Map();
|
|
24
|
+
for (const device of devices) {
|
|
25
|
+
for (const node of device.nodes) {
|
|
26
|
+
counts.set(node, (counts.get(node) ?? 0) + 1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return counts;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Nodes where a transformer meets a **selector switch** and nothing else.
|
|
33
|
+
*
|
|
34
|
+
* Connectivity, never a spelling: a node qualifies when the devices touching it are one
|
|
35
|
+
* transformer and one or more plain `switch`es, with no third kind. An output transformer's
|
|
36
|
+
* impedance selector is exactly that shape -- `hiwatt-dr103`'s `SW_IMPEDANCE_SELECTOR` has one
|
|
37
|
+
* `common` and three throws, each throw sharing a node with one secondary tap of
|
|
38
|
+
* `T_OUTPUT_TH7549_2`.
|
|
39
|
+
*
|
|
40
|
+
* **`switch` and not `selector`, deliberately, and this is the whole boundary of this rule.** This
|
|
41
|
+
* repository already models a real 1-of-N selector as its own device kind: `selector` stamps every
|
|
42
|
+
* throw of every pole and lets a control decide which conducts, resolving its position from a
|
|
43
|
+
* declared `Options:` list against `Position:`. That is the right answer for an ohms selector -- it
|
|
44
|
+
* makes the taps *switchable*, so the reflected load changes with the selection, which is the half
|
|
45
|
+
* that matters for power-stage distortion.
|
|
46
|
+
*
|
|
47
|
+
* These two packets do not reach it: they declare `kind: switch` with a `SelectedState: 16 ohms`
|
|
48
|
+
* property rather than the `Options`/`Position` pair the classifier reads. So this rule is the
|
|
49
|
+
* narrow, exact thing that can be said meanwhile -- an unselected throw is open, and an open
|
|
50
|
+
* secondary contributes nothing -- and it **stops applying by construction** the moment a packet
|
|
51
|
+
* declares its selector properly, because a `selector` is not a `switch` and this predicate counts
|
|
52
|
+
* only the latter. It cannot defeat the better model; it is superseded by it.
|
|
53
|
+
*/
|
|
54
|
+
export function selectorTapNodes(devices) {
|
|
55
|
+
const kinds = new Map();
|
|
56
|
+
for (const device of devices) {
|
|
57
|
+
for (const node of new Set(device.nodes)) {
|
|
58
|
+
const entry = kinds.get(node) ?? {
|
|
59
|
+
transformers: 0,
|
|
60
|
+
switches: 0,
|
|
61
|
+
others: 0,
|
|
62
|
+
};
|
|
63
|
+
if (device.kind === "transformer") {
|
|
64
|
+
entry.transformers += 1;
|
|
65
|
+
}
|
|
66
|
+
else if (device.kind === "switch") {
|
|
67
|
+
entry.switches += 1;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
entry.others += 1;
|
|
71
|
+
}
|
|
72
|
+
kinds.set(node, entry);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const taps = new Set();
|
|
76
|
+
for (const [node, entry] of kinds) {
|
|
77
|
+
if (entry.transformers === 1 && entry.switches >= 1 && entry.others === 0) {
|
|
78
|
+
taps.add(node);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return taps;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The coils this transformer declares, reduced to the pairs of nodes a stamp needs.
|
|
85
|
+
*
|
|
86
|
+
* **Read, not reconstructed.** Until `@vessel-dsp/core@0.6.35` a transformer's terminals gave no
|
|
87
|
+
* statement of which coil each belonged to, so this stage grouped them with a 110-entry table
|
|
88
|
+
* keyed on folded terminal spellings -- `primaryplus`, `hvreda345vac`, `powertubeheatercenter0v`.
|
|
89
|
+
* That table covered the corpus because it was written from the corpus, one packet at a time, and
|
|
90
|
+
* a transformer nobody had transcribed yet arrived as a refusal naming a winding class instead of
|
|
91
|
+
* the real fault, which was that the document never said what its coils were.
|
|
92
|
+
*
|
|
93
|
+
* Everything the table encoded beyond the grouping stays where it was:
|
|
94
|
+
*
|
|
95
|
+
* - **`end: a|b|tap` is coil order plus each terminal's own role.** The ends are the terminals
|
|
96
|
+
* whose declared role is `winding`; a `windingTap` sits physically where the list puts it.
|
|
97
|
+
* - **`end: unconnected` was never winding structure.** A tap the document wires to nothing is a
|
|
98
|
+
* connectivity fact, read from `terminalOccurrences` below exactly as before.
|
|
99
|
+
* - **`end: selectable` likewise.** Which mains tap is live is a property of the selector switch,
|
|
100
|
+
* and the refusal below still names that switch rather than the transformer.
|
|
101
|
+
*/
|
|
102
|
+
export function transformerWindings(device, law, terminalOccurrences, selectorTaps) {
|
|
103
|
+
const declared = device.identity.declaredWindings;
|
|
104
|
+
if (declared === null) {
|
|
105
|
+
throw new LoweringError(`transformer ${device.id} declares no windings, so which of its terminals form each ` +
|
|
106
|
+
"coupled coil is unstated -- a coil grouping is a fact about the transformer that " +
|
|
107
|
+
"this stage reads from the document and will not infer from terminal spellings", device.id);
|
|
108
|
+
}
|
|
109
|
+
const groups = new Map();
|
|
110
|
+
for (const [index, winding] of declared.entries()) {
|
|
111
|
+
const nodes = winding.terminalIndices.flatMap((terminal) => {
|
|
112
|
+
const node = device.nodes[terminal];
|
|
113
|
+
return node === undefined ? [] : [node];
|
|
114
|
+
});
|
|
115
|
+
if (nodes.length === 0) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const key = windingKey(winding.role, winding.id, groups);
|
|
119
|
+
const centerTap = winding.centerTapAt === null ? undefined : nodes[winding.centerTapAt];
|
|
120
|
+
// Ratings arrive as terminal indices; the reduction and the stamps work in nodes.
|
|
121
|
+
const ratedOhms = new Map();
|
|
122
|
+
for (const rating of winding.impedances) {
|
|
123
|
+
const [from, to] = rating.across;
|
|
124
|
+
const ends = [device.nodes[from], device.nodes[to]].filter((node) => node !== undefined);
|
|
125
|
+
// A rating names the pair it spans, and the reference end of that pair is shared by
|
|
126
|
+
// every rating on the coil. What a stamp needs is the *other* end -- the tap -- so
|
|
127
|
+
// the rating is keyed by whichever node is not the coil's reference.
|
|
128
|
+
const reference = centerTap ?? nodes[0];
|
|
129
|
+
const tap = ends.find((node) => node !== reference) ?? ends[0];
|
|
130
|
+
if (tap !== undefined) {
|
|
131
|
+
ratedOhms.set(tap, rating.ohms);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
groups.set(key, {
|
|
135
|
+
role: winding.role,
|
|
136
|
+
a: nodes[0],
|
|
137
|
+
b: nodes.length > 1 ? nodes[nodes.length - 1] : undefined,
|
|
138
|
+
centerTap,
|
|
139
|
+
// An output tap is an alternative the coil is not simultaneously live at, so the
|
|
140
|
+
// reference tap is not one of them.
|
|
141
|
+
taps: nodes.slice(1, -1).filter((node) => node !== centerTap),
|
|
142
|
+
amplitudeVolts: law.windingAmplitudeVolts[index] ?? null,
|
|
143
|
+
ratedOhms,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// A coil brought out as several taps needs to be reduced to the pair a stamp can hold, and
|
|
147
|
+
// which pair that is comes from connectivity: the tap something else in the document touches
|
|
148
|
+
// is the live one, and an open tap on an ideal transformer carries no current and reflects
|
|
149
|
+
// nothing, which makes dropping it exact rather than an approximation.
|
|
150
|
+
//
|
|
151
|
+
// The reduction pivots the coil onto the live tap: that tap becomes one end and the coil's
|
|
152
|
+
// other end -- the common -- stays the return. This is what the old table wrote by hand as
|
|
153
|
+
// `secondary16white: end "a"` against `secondarycommonblack: end "b"`, and what its
|
|
154
|
+
// `secondaryalt3`/`secondaryalt2` promotion loop then had to re-derive by preferring 16 over 8
|
|
155
|
+
// over 4 by spelling.
|
|
156
|
+
for (const [name, group] of [...groups]) {
|
|
157
|
+
if (group.taps.length === 0) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const alternates = [...group.taps, ...(group.b === undefined ? [] : [group.b])];
|
|
161
|
+
const live = alternates.filter((node) => (terminalOccurrences.get(node) ?? 0) > 1);
|
|
162
|
+
const selected = live.filter((node) => !selectorTaps.has(node));
|
|
163
|
+
const chosen = selected.length > 0 ? selected : live;
|
|
164
|
+
if (chosen.length === 0) {
|
|
165
|
+
// Nothing on the coil is wired: it is dangling and the drop below removes it.
|
|
166
|
+
groups.set(name, { ...group, taps: [] });
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
// **Every live tap is stamped, not just one.** A tapped secondary with two loaded taps is
|
|
170
|
+
// two coupled windings sharing a common, and each takes the turns ratio its own rating
|
|
171
|
+
// gives. Collapsing to one tap silently dropped whatever was on the others -- which is
|
|
172
|
+
// what happened to `orange-rockerverb`'s 8 Ω speaker jack and its feedback resistor.
|
|
173
|
+
//
|
|
174
|
+
// A rating is what makes the extra tap stampable, so a live tap without one refuses.
|
|
175
|
+
// Nothing else in the document says how many turns it sits at.
|
|
176
|
+
const unrated = chosen.filter((node) => !group.ratedOhms.has(node));
|
|
177
|
+
if (chosen.length > 1 && unrated.length > 0) {
|
|
178
|
+
throw new LoweringError(`transformer ${device.id}: winding "${name}" has ${chosen.length} taps carrying a load ` +
|
|
179
|
+
`at once and ${unrated.length} of them state no rated impedance (nodes ` +
|
|
180
|
+
`${unrated.join(", ")}) -- each loaded tap needs its own rating for a turns ` +
|
|
181
|
+
"ratio, and this stage will not guess where on the coil a tap sits", device.id);
|
|
182
|
+
}
|
|
183
|
+
// The coil now spans the common to a live tap, so any reference tap it also declared is
|
|
184
|
+
// outside that span and no longer part of what is stamped. No corpus coil declares both.
|
|
185
|
+
groups.delete(name);
|
|
186
|
+
for (const tap of chosen) {
|
|
187
|
+
groups.set(windingKey(group.role, null, groups), {
|
|
188
|
+
role: group.role,
|
|
189
|
+
a: tap,
|
|
190
|
+
b: group.a,
|
|
191
|
+
centerTap: undefined,
|
|
192
|
+
taps: [],
|
|
193
|
+
amplitudeVolts: group.amplitudeVolts,
|
|
194
|
+
ratedOhms: group.ratedOhms,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// A winding brought out as several selectable taps needs the selector's own position, and
|
|
199
|
+
// nothing in this document states one. Refused here rather than guessed, and refused *naming
|
|
200
|
+
// the selector* rather than the transformer: the misleading version of this said the primary
|
|
201
|
+
// "has only one terminal declared", which sends a reader to the winding when the missing fact
|
|
202
|
+
// is a switch position.
|
|
203
|
+
//
|
|
204
|
+
// **An unselected throw of a plain make-or-break selector is dropped instead**, and the
|
|
205
|
+
// condition is a second winding to fall back on: a selector connects its common to exactly one
|
|
206
|
+
// throw, so every other tap is open, and an open winding on an ideal transformer carries no
|
|
207
|
+
// current and reflects nothing. `TransformerLaw.turnsRatio` already states that intent --
|
|
208
|
+
// "exact for a transformer with one secondary (tapped or not)". Silent for the same reason the
|
|
209
|
+
// dangling drop below is: lowering has no warning channel, and what is dropped provably cannot
|
|
210
|
+
// change the solved circuit.
|
|
211
|
+
for (const [name, group] of [...groups]) {
|
|
212
|
+
if (group.b !== undefined || !selectorTaps.has(group.a)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if ([...groups].some(([other, candidate]) => other !== name && candidate.b !== undefined)) {
|
|
216
|
+
groups.delete(name);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
throw new LoweringError(`transformer ${device.id}: winding "${name}" reaches the rest of the document only ` +
|
|
220
|
+
`through a selector (node ${group.a}) and the document states no selected throw ` +
|
|
221
|
+
"for it -- which tap is live is a property of that switch, not of a terminal's " +
|
|
222
|
+
"spelling, and this stage will not pick one", device.id);
|
|
223
|
+
}
|
|
224
|
+
// A winding no end of which connects anywhere else in the document is wired to nothing, and
|
|
225
|
+
// is dropped. Checked by connectivity, never by spelling. `fender-5e3-deluxe-tweed`'s power
|
|
226
|
+
// transformer is the case this was written for: its `filament_a`/`filament_b` pair is
|
|
227
|
+
// declared, typed and touched by no other component, so stamping it would put a source across
|
|
228
|
+
// two rows nothing else holds, which only `gmin` then references. Ground is never dangling, so
|
|
229
|
+
// a winding returning to node 0 is always kept.
|
|
230
|
+
for (const [name, group] of [...groups]) {
|
|
231
|
+
const ends = [group.a, group.b, group.centerTap, ...group.taps].filter((node) => node !== undefined);
|
|
232
|
+
if (ends.every((node) => (terminalOccurrences.get(node) ?? 0) <= 1)) {
|
|
233
|
+
groups.delete(name);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (group.b !== undefined) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (group.role === "bias") {
|
|
240
|
+
// A single-ended bias winding returns inside the transformer. Ten corpus power
|
|
241
|
+
// transformers declare exactly this, and core warns about it (`winding-single-ended`)
|
|
242
|
+
// so the shape stays visible rather than becoming a silent convention here.
|
|
243
|
+
groups.set(name, { ...group, b: GROUND });
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
throw new LoweringError(`transformer ${device.id}: winding "${name}" declares one terminal, and its node ` +
|
|
247
|
+
`${group.a} connects to another component -- this stage has no model for a used ` +
|
|
248
|
+
"single-ended tap, so it refuses rather than guessing what it means", device.id);
|
|
249
|
+
}
|
|
250
|
+
// A grounded end is the coil's return, so it is the one a stamp measures *from*. Coil order
|
|
251
|
+
// states where the turns are, not a polarity -- the two ends of a winding have no inherent
|
|
252
|
+
// plus and minus -- but a winding stamped with its return as the plus end is inverted against
|
|
253
|
+
// everything that shares that return. Last, because the tap reduction above already puts the
|
|
254
|
+
// common in `b`, and doing it first would offer ground itself as a live alternate.
|
|
255
|
+
for (const [name, group] of groups) {
|
|
256
|
+
if (group.b !== undefined && group.a === GROUND && group.b !== GROUND) {
|
|
257
|
+
groups.set(name, { ...group, a: group.b, b: group.a });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// A transformer is on the driven path when at least one coil states its own voltage. Tested
|
|
261
|
+
// with `some`, not with the list's length: the list carries one slot per declared coil and a
|
|
262
|
+
// slot is `null` when the source states nothing, so every transformer with any windings has a
|
|
263
|
+
// non-zero length.
|
|
264
|
+
const windings = law.windingAmplitudeVolts.some((volts) => volts !== null)
|
|
265
|
+
? drivenWindings(device, law, groups)
|
|
266
|
+
: coupledWindings(device, law.turnsRatio, groups);
|
|
267
|
+
if (windings.length === 0) {
|
|
268
|
+
throw new LoweringError(`transformer ${device.id} has a primary and no secondary winding`, device.id);
|
|
269
|
+
}
|
|
270
|
+
return windings;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The impedance this coil is rated at across the pair a stamp uses, or 0 when it states none.
|
|
274
|
+
*
|
|
275
|
+
* Both ends are tried because which one carries the rating depends on the coil: a primary is
|
|
276
|
+
* rated plate-to-plate and a reduced secondary is rated at the live tap that became its `a`.
|
|
277
|
+
*/
|
|
278
|
+
function ratedOhmsOf(group) {
|
|
279
|
+
const ohms = group.ratedOhms.get(group.a) ??
|
|
280
|
+
(group.b === undefined ? undefined : group.ratedOhms.get(group.b));
|
|
281
|
+
return ohms !== undefined && ohms > 0 ? ohms : 0;
|
|
282
|
+
}
|
|
283
|
+
/** The key of the coil whose role is `primary`, for the reference-swap comparison below. */
|
|
284
|
+
function primaryName(groups) {
|
|
285
|
+
for (const [name, group] of groups) {
|
|
286
|
+
if (group.role === "primary" || group.role === "drive") {
|
|
287
|
+
return name;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return "primary";
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* A key for a coil, unique within its transformer.
|
|
294
|
+
*
|
|
295
|
+
* A role may repeat: `orange-rockerverb`'s power transformer carries two filament windings, a
|
|
296
|
+
* 3.15-0-3.15 V pair for the power tubes and a 6.3 V pair for the preamp. The declared `id`
|
|
297
|
+
* distinguishes them where the document gives one; otherwise the role is suffixed, which is all
|
|
298
|
+
* `secondaryalt2` ever was.
|
|
299
|
+
*/
|
|
300
|
+
function windingKey(role, id, groups) {
|
|
301
|
+
const base = id ?? role;
|
|
302
|
+
if (!groups.has(base)) {
|
|
303
|
+
return base;
|
|
304
|
+
}
|
|
305
|
+
for (let suffix = 2;; suffix += 1) {
|
|
306
|
+
const candidate = `${base}#${suffix}`;
|
|
307
|
+
if (!groups.has(candidate)) {
|
|
308
|
+
return candidate;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Each winding driven at its own stated EMF, with no primary modelled.
|
|
314
|
+
*
|
|
315
|
+
* The `primary` group is skipped rather than required: on this path it is the mains side, it
|
|
316
|
+
* carries no audio, and the whole point is that the document need not say anything about it.
|
|
317
|
+
*/
|
|
318
|
+
function drivenWindings(device, law, groups) {
|
|
319
|
+
const frequencyHz = law.mainsFrequencyHz;
|
|
320
|
+
if (frequencyHz === null) {
|
|
321
|
+
throw new LoweringError(`transformer ${device.id} is specified by its winding voltages, but this document ` +
|
|
322
|
+
"states no single AC supply frequency for those windings to run at -- a voltage " +
|
|
323
|
+
"with no frequency is not a waveform, and this stage will not pick one", device.id);
|
|
324
|
+
}
|
|
325
|
+
const windings = [];
|
|
326
|
+
for (const [name, group] of groups) {
|
|
327
|
+
if (group.role === "primary" || group.role === "drive") {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
const { a, b } = group;
|
|
331
|
+
if (b === undefined) {
|
|
332
|
+
throw new LoweringError(`transformer ${device.id}: winding "${name}" has no pair of ends`, device.id);
|
|
333
|
+
}
|
|
334
|
+
const tap = group.centerTap;
|
|
335
|
+
const amplitudeVolts = group.amplitudeVolts;
|
|
336
|
+
if (amplitudeVolts === null) {
|
|
337
|
+
// **A coil whose source states no voltage is not driven.** This replaced a five-name
|
|
338
|
+
// `HEATER_CLASS_WINDINGS` set that excused the same thing by class, which could not
|
|
339
|
+
// see the reason: `fender-bassman`'s rectifier heater is the only corpus coil in this
|
|
340
|
+
// position, and its packet's own `Derivation` says the 5 V is "assumed from GZ34
|
|
341
|
+
// heater, unprinted on selected schematic" and that typing it would be the
|
|
342
|
+
// invented-typical-value inference the source discipline forbids. So the absence is
|
|
343
|
+
// the packet's decision, not an omission, and the class of the coil is irrelevant to
|
|
344
|
+
// it.
|
|
345
|
+
//
|
|
346
|
+
// The risk this accepts is a *wired* coil left undriven. That is loud rather than
|
|
347
|
+
// silent for anything carrying audio -- an undriven HV winding is a dead B+ rail and
|
|
348
|
+
// a silent amp -- and `requireWindingSpecification` in `netlist.ts` refuses a
|
|
349
|
+
// transformer where no coil states a voltage at all.
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
// A centre tap is two sources of the stated size about the tap, so the two ends swing in
|
|
353
|
+
// antiphase and the rectifier downstream is full-wave. Never one source of twice the size.
|
|
354
|
+
const halves = tap === undefined
|
|
355
|
+
? [{ plus: a, minus: b }]
|
|
356
|
+
: [
|
|
357
|
+
{ plus: a, minus: tap },
|
|
358
|
+
{ plus: tap, minus: b },
|
|
359
|
+
];
|
|
360
|
+
for (const half of halves) {
|
|
361
|
+
windings.push({
|
|
362
|
+
kind: "driven",
|
|
363
|
+
plus: half.plus,
|
|
364
|
+
minus: half.minus,
|
|
365
|
+
amplitudeVolts,
|
|
366
|
+
frequencyHz,
|
|
367
|
+
sourceOhms: law.windingSourceOhms,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return windings;
|
|
372
|
+
}
|
|
373
|
+
/** Each secondary coupled to the shared primary through the declared turns ratio. */
|
|
374
|
+
function coupledWindings(device, declaredRatio, groups) {
|
|
375
|
+
// `drive` is a primary in every sense this reduction cares about: it is the coil the signal
|
|
376
|
+
// enters, and the others are referred to it. It is a separate role because a spring tank's
|
|
377
|
+
// coils do not transform each other's voltage -- but a tank shell whose part number is not a
|
|
378
|
+
// tank's lowers here as an ordinary transformer, and then the drive coil is the primary.
|
|
379
|
+
const primary = [...groups.values()].find((group) => group.role === "primary" || group.role === "drive");
|
|
380
|
+
if (primary === undefined || primary.b === undefined) {
|
|
381
|
+
throw new LoweringError(`transformer ${device.id} has no complete primary winding`, device.id);
|
|
382
|
+
}
|
|
383
|
+
// A tapped primary has no single reference winding of its own -- see the docstring's
|
|
384
|
+
// derivation -- so the shared-primary reduction pivots on any OTHER complete, untapped
|
|
385
|
+
// winding instead, which sees the same core flux and can stand in for it.
|
|
386
|
+
let referenceName = primaryName(groups);
|
|
387
|
+
let referenceGroup = primary;
|
|
388
|
+
let reference = { a: primary.a, b: primary.b };
|
|
389
|
+
if (primary.centerTap !== undefined) {
|
|
390
|
+
const candidates = [...groups.entries()].filter((entry) => {
|
|
391
|
+
const [, group] = entry;
|
|
392
|
+
return (group.role !== "primary" &&
|
|
393
|
+
group.role !== "drive" &&
|
|
394
|
+
group.b !== undefined &&
|
|
395
|
+
group.centerTap === undefined);
|
|
396
|
+
});
|
|
397
|
+
if (candidates.length === 0) {
|
|
398
|
+
throw new LoweringError(`transformer ${device.id} has a tapped primary and no untapped winding to use as a ` +
|
|
399
|
+
"reference instead, which this stage cannot reduce to coupled pairs", device.id);
|
|
400
|
+
}
|
|
401
|
+
// Several candidates are the loaded taps of one physical secondary, which the reduction
|
|
402
|
+
// above split into a group each. Any of them can serve -- they all see the same core, and
|
|
403
|
+
// every ratio here is taken against whichever one this picks -- so the highest-rated is
|
|
404
|
+
// chosen: it is the coil's far end and therefore the most complete statement of it.
|
|
405
|
+
const [name, group] = candidates.reduce((best, entry) => ratedOhmsOf(entry[1]) > ratedOhmsOf(best[1]) ? entry : best);
|
|
406
|
+
referenceName = name;
|
|
407
|
+
referenceGroup = group;
|
|
408
|
+
reference = { a: group.a, b: group.b };
|
|
409
|
+
}
|
|
410
|
+
// The rating of the reference coil, against which every other coil's ratio is taken.
|
|
411
|
+
const referenceOhms = ratedOhmsOf(referenceGroup) || null;
|
|
412
|
+
const windings = [];
|
|
413
|
+
for (const [name, group] of groups) {
|
|
414
|
+
if (name === referenceName) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
const { a, b } = group;
|
|
418
|
+
if (b === undefined) {
|
|
419
|
+
throw new LoweringError(`transformer ${device.id}: winding "${name}" has no pair of ends`, device.id);
|
|
420
|
+
}
|
|
421
|
+
const tap = group.centerTap;
|
|
422
|
+
// The tapped primary, reflected through a swapped reference, uses the inverse of the
|
|
423
|
+
// declared ratio, halved -- worked out in the docstring above.
|
|
424
|
+
const isSwappedPrimary = group.role === "primary" || group.role === "drive";
|
|
425
|
+
// **A coil's ratio comes from its own rating**, which is what lets two loaded taps of one
|
|
426
|
+
// secondary be stamped at different ratios. `declaredRatio` is already
|
|
427
|
+
// `sqrt(Zreference / Zcoil)` for a transformer whose ratings this derives from, so for the
|
|
428
|
+
// single-rating coils that is the same arithmetic on the same numbers; the rated path is
|
|
429
|
+
// what the extra taps need.
|
|
430
|
+
//
|
|
431
|
+
// The swapped primary keeps `declaredRatio`: its formula is `2 / sqrt(Zp/Zs)`, and
|
|
432
|
+
// recomputing that as `2 * sqrt(Zs/Zp)` is the same value by algebra and not always the
|
|
433
|
+
// same double.
|
|
434
|
+
//
|
|
435
|
+
// `turnsRatio` on a coupled stamp is (reference turns)/(coil turns), and turns go as the
|
|
436
|
+
// square root of impedance, so a rating at each end of the pair states it completely.
|
|
437
|
+
const coilOhms = ratedOhmsOf(group) || null;
|
|
438
|
+
const rated = referenceOhms !== null && coilOhms !== null;
|
|
439
|
+
const coilRatio = rated
|
|
440
|
+
? Math.sqrt(referenceOhms / coilOhms)
|
|
441
|
+
: declaredRatio;
|
|
442
|
+
// The swapped primary keeps the reciprocal *expression* the previous rung used rather
|
|
443
|
+
// than the algebraically equal `2 * sqrt(Zref / Zcoil)`: the two agree to within a double's
|
|
444
|
+
// last bit, and the point of reading ratings is to fix a wrong ratio, not to perturb the
|
|
445
|
+
// ten packets whose ratio was already right.
|
|
446
|
+
const localRatio = isSwappedPrimary
|
|
447
|
+
? 2 /
|
|
448
|
+
(rated
|
|
449
|
+
? Math.sqrt(coilOhms / referenceOhms)
|
|
450
|
+
: declaredRatio)
|
|
451
|
+
: coilRatio;
|
|
452
|
+
const halves = tap === undefined
|
|
453
|
+
? [{ plus: a, minus: b, ratio: localRatio }]
|
|
454
|
+
: isSwappedPrimary
|
|
455
|
+
? [
|
|
456
|
+
{ plus: a, minus: tap, ratio: localRatio },
|
|
457
|
+
{ plus: tap, minus: b, ratio: localRatio },
|
|
458
|
+
]
|
|
459
|
+
: [
|
|
460
|
+
{ plus: a, minus: tap, ratio: coilRatio * 2 },
|
|
461
|
+
{ plus: tap, minus: b, ratio: coilRatio * 2 },
|
|
462
|
+
];
|
|
463
|
+
for (const half of halves) {
|
|
464
|
+
windings.push({
|
|
465
|
+
kind: "coupled",
|
|
466
|
+
primaryPlus: reference.a,
|
|
467
|
+
primaryMinus: reference.b,
|
|
468
|
+
plus: half.plus,
|
|
469
|
+
minus: half.minus,
|
|
470
|
+
turnsRatio: half.ratio,
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return windings;
|
|
475
|
+
}
|
|
476
|
+
//# sourceMappingURL=transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.js","sourceRoot":"","sources":["../src/transformer.ts"],"names":[],"mappings":"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"}
|