::BandGap::schema — known/required param sets per model, consumed by
::Pull::resolve_select_one at slice-materialization time (typo guard
per chain link + required-present on the merged params). Values may
be composition-rule lists; validation is key-based.
::Bands::__compose_mobility
file: TclLib/Models/Bands/compose.tcl
Per-band mobility composer. Mathiessen-sums the band's declared
Mobility models; applies optional HighFieldMobility wrap. Each
model's sub-dict still uses the per-carrier shape ({electron {…}
hole {…}}); the band's quasi_fermi picks which carrier slice to
dispatch.
::Bands::__compose_population
file: TclLib/Models/Bands/compose.tcl
Per-band population — Fermi-Dirac selector.
::Bands::__family_shift
file: TclLib/Models/Bands/compose.tcl
Per-band strain shift dispatch — X/L family bands compute via the
XBandEdgeShiftStrain / LBandEdgeShiftStrain Tcl helpers; other
families default to zero (override via explicit `shift` key in the
band slice). `miller` comes from ctx (the `device pull miller=`
argument, default (001)<100>).
::BandStructure::__assign_family_shifts
file: TclLib/Models/BandStructure/compose.tcl
Strain shift assignment per valley family. Stores into the upvar'd
shifts array. X-family valleys get XBandEdgeShiftStrain entries
indexed by their |Dir|; L-family valleys get LBandEdgeShiftStrain;
Γ-family valleys get a (currently zero) hydrostatic shift.
::BandStructure::__compose_flat
file: TclLib/Models/BandStructure/compose.tcl
Single-effective-band emission.
::BandStructure::__compose_multivalley
file: TclLib/Models/BandStructure/compose.tcl
Multi-valley emission (lifted from BandstructurePackage steps
2/4/5/7/8/10 as pure function).
::BandStructure::__hole_solution_name
file: TclLib/Models/BandStructure/compose.tcl
Map schema band names (LH/HH/SO) to the legacy solution names that
downstream code (avalanche, B2B, Schenk) reads. Unknown band names
pass through verbatim so materials can introduce additional bands.
::BandStructure::__install_strain_params
file: TclLib/Models/BandStructure/compose.tcl
Install per-material deformation potentials from a `BandStructure {
StrainParams { … } }` dict slice into `::<mat>::<key>` namespace
vars. Compat shim for the Tcl strain helpers (XBandEdgeShiftStrain
in TclLib/Device/Utilities/Strain/XValley.tcl, LBandEdgeShiftStrain
in LValley.tcl, __Compliance / __Stiffness in scalartensor.tcl) that
still read namespace vars by qualified name. Compose::eval_value
handles composition rules (`{linear A B}` for SiGe) at install time
using the material's `x` from ctx.
Idempotent — re-running with the same dict produces the same vars.
The dict is the source of truth; F3 deletes this proc when the
helpers take args.
::Compose::eval_numeric
file: TclLib/Models/Combinators.tcl
::Compose::eval_numeric — numeric twin of eval_value for Tcl-time
consumers (the stress kernels do their matrix math in Tcl, so
composition-dependent stiffnesses must resolve to NUMBERS at pull
time, not Alagator strings). `x` is the material's composition
fraction (numeric); plain scalar values pass through verbatim.
Rules:
linear A B → A*(1-x) + B*x
linear_bowing A B bowing b → A*(1-x) + B*x - b*x*(1-x)
linear_neg A B → -(A*(1-x) + B*x)
poly_T … → error (needs Temp at solve time —
not expressible numerically here)
::ConductivityMultiplier::schema — known/required param sets per
model, consumed by ::Pull::resolve_select_one.
::Defaults::device
file: TclLib/Models/Defaults.tcl
::Defaults::device — returns a copy of the device-domain master.
Lazy-sources every baseline.tcl on first call.
::Defaults::diffuse
file: TclLib/Models/Defaults.tcl
::Defaults::diffuse — returns a copy of the diffusion-domain master.
Lazy-sources every baseline.tcl on first call.
::Defaults::register
file: TclLib/Models/Defaults.tcl
::Defaults::register <mat> <full_dict>
Splits a material's full physics dict by family name into stress-
domain, device-domain, and diffusion-domain slices and stores each
in the corresponding subsystem-specific global. Baselines call
this at source time.
::Defaults::stress
file: TclLib/Models/Defaults.tcl
::Defaults::stress — returns a copy of the stress-domain master.
Lazy-sources every baseline.tcl on first call.
::Device::__flag_present
file: TclLib/Models/Render.tcl
Internal: does a flag (literal token) appear in the flags list?
::Device::__resolve_selone — chain-aware select-one slice resolution.
Calls `::Pull::resolve_select_one` on the UN-merged models dict to
pick the closest ancestor's declared model and chain-merge params
within it, returning `{<chosen_model> <merged_params>}` wrapped as a
single-entry dict. Empty dict when no link declares the family.
`resolve deep` families don't come through here — their slice is
exactly the family's share of the material's full deep merge, so the
dispatcher consumes it straight from `wd` (one chain walk per
material instead of one per family).
::Device::__result_get
file: TclLib/Models/DeviceWrapper.tcl
::Device::__result_get — return ctx.__results__.<family> as a dict,
defaulting to an empty dict when the family didn't emit (or never
ran). Replaces the open-coded `[dict exists … ? dict get : dict
create]` idiom that used to appear in every downstream composer.
::Device::__result_has
file: TclLib/Models/DeviceWrapper.tcl
::Device::__result_has — does ctx have a non-empty key from the
named family's published result dict? Used by composers to check
upstream emissions (e.g. BandStructure published Elec).
::Device::Aggregate::__dir_projection
file: TclLib/Models/Aggregate/compose.tcl
Project a direction vector onto axes — returns dict {x sign y sign z sign}
where sign is "1", "-1", or "0" for null projection.
::Device::assert_consumed
file: TclLib/Models/Inheritance.tcl
::Device::assert_consumed <where> <mat> <wd>
Per-material leftover check used by both `device pull` and `stress
pull` dispatchers. Raises when any family is left in $wd after the
subsystem's composers have consumed their share, naming the
subsystem ($where prefix), the material, and the leftover families.
Catches "deck passed an out-of-domain dict" (e.g. unfiltered
::Models handed to stress pull) and "subsystem composer forgot to
consume its family". Single source of truth for the error format.
::Device::consume
file: TclLib/Models/Inheritance.tcl
::Device::consume <dictvar> <key> ?<default>?
Reads and removes a key from a dict variable in one shot. Returns
the value (or $default if the key is absent). This is how the
top-level dispatcher implements consume-and-validate: each family
entry is read and removed as it dispatches; any unconsumed key at
the end raises.
::Device::dict_deep_merge
file: TclLib/Models/Inheritance.tcl
::Device::dict_deep_merge <parent> <child>
Recursive leaf-level merge. At each level: if a key exists in both
parent and child AND both values are themselves dicts, recurse.
Otherwise child wins.
::Device::dos_m32
file: TclLib/Models/BandStructure/dir.tcl
DOS-mass term for BandEdgeNumberOfStates' linear m-slot.
BandEdgeNumberOfStates returns T^1.5 * m * const^1.5 — its `m`
argument is the DOS effective mass RAISED TO 3/2, not the mass
itself (Nc ∝ m_dos^{3/2}). For an ellipsoidal valley
m_dos = (ml·mt²)^(1/3), so the slot takes (ml·mt²)^(1/2).
This was computed inline (with diverging exponents — Bands and
MatNcTotal passed the raw (ml·mt²)^(1/3), under-counting Nc by
m_dos^{1/2}) in three places; every valley-mass consumer goes
through here now. Numeric masses fast-path to a number;
composition-rule strings stay symbolic.
::Device::is_dict
file: TclLib/Models/Inheritance.tcl
::Device::is_dict <value>
Heuristic: a Tcl value is "dict-like" if it has even length AND
`dict size` succeeds on it. Used to decide whether deep_merge
should recurse at this level or treat the value as a leaf. Lists
(like Dir = {1 0 0}) have odd length only for odd-element lists,
so {Dir {1 0 0}} treats the {1 0 0} as 1-element dict at this
heuristic — accepted because {1 0 0} merging never recurses into
0/0 the way leaf-overrides need. Acceptable false-positive for
the rare 3-element direction value.
A cleaner alternative is to mark dict values explicitly, but the
heuristic works for every value shape FLOOXS actually uses.
::Device::lowest_affinity
file: TclLib/Models/BandStructure/dir.tcl
Compose a nested-ternary "max over a list" Alagator expression.
Dedupes identical entries first so a 6-valley X-only material with
shared χ collapses to a trivial constant. Caller supplies the list;
rule-evaluation (Compose::eval_value for composition rules) happens
upstream — this proc treats every entry as opaque.
::Device::render
file: TclLib/Models/Render.tcl
::Device::render <mat> <decls>
Iterate decls (a dict of name → spec) and emit one `solution $mat
add ...` call per entry. The order is dict-iteration order, which
in Tcl is insertion order, which equals the order the upstream
compose procs returned their spec dicts. Per-material registration
semantics; cross-material solutions stay outside this composer
(FEQFDevicePackage sets them up before the pull walks materials).
::Device::resolve_models
file: TclLib/Models/Inheritance.tcl
::Device::resolve_models <mat> ?<models_dict>?
Returns the effective ::Models-style dict for $mat — recursive deep
merge of every link in `mater name=$mat chain` (root first, child
last, so child values win at leaf level). Materials with no entry
contribute nothing to the merge.
If `models_dict` is supplied, walks IT instead of the `::Models`
global. Empty string (the default) means "use ::Models". Used by
the explicit `device pull=$dict` path where the deck owns the dict
locally.
Returns an empty dict if no link in the chain has an entry.
::Device::valley_l_dir_index
file: TclLib/Models/BandStructure/dir.tcl
Index a {111}-family direction into LBandEdgeShiftStrain's flat list.
Returns 0/1/2/3 for the four (111) variants; raises on anything else.
::Device::valley_x_dir_index
file: TclLib/Models/BandStructure/dir.tcl
Index an axis-aligned direction into XBandEdgeShiftStrain's flat list.
Accepts {±1 0 0}/{0 ±1 0}/{0 0 ±1} (the six X-valley directions);
strain shifts are symmetric across the sign so we work in |dir|.
::Elastic::atensor
file: TclLib/Models/Elastic.tcl
::Elastic::atensor — full anisotropic ATensor Alagator substring from
the first twelve entries of a packed stiffness list.
::Elastic::cubic_cij
file: TclLib/Models/Elastic.tcl
::Elastic::cubic_cij — rotated cubic stiffness for an arbitrary
Miller orientation.
Args:
C11, C12, C44 — cubic stiffness constants in crystal frame
(dynes/cm^2 or Pa)
Miller — orientation in (hkl)<uvw> notation; default (001)<100>
Returns the packed 15-element list (see pack_cij above).
::Elastic::cubic_stiffness
file: TclLib/Models/Elastic.tcl
::Elastic::cubic_stiffness — cubic 6x6 stiffness matrix in crystal
frame from C11, C12, C44.
::Elastic::hex_cij
file: TclLib/Models/Elastic.tcl
::Elastic::hex_cij — hexagonal (wurtzite / 4H-6H SiC) stiffness from
the five independent constants, c-axis carried by the chosen device
axis (no rotation — axis-aligned only; C66 = (C11-C12)/2 within the
basal plane).
Args:
C11 C12 C13 C33 C44 — hexagonal stiffness constants (crystal
convention: c-axis = 3-direction)
axis — device axis carrying the crystal c-axis
(x | y | z; default x, matching the
transiso_cij convention)
Thermodynamic stability is enforced (C11 > |C12| and
(C11+C12)*C33 > 2*C13^2) — a violating set is a deck typo, not a
material.
Returns the packed 12-element list (normal 3x3 block row-major,
then xy / yz / xz shear stiffnesses — the ::Elastic::atensor order).
::Elastic::pack_cij
file: TclLib/Models/Elastic.tcl
::Elastic::pack_cij — pack a rotated 6x6 stiffness matrix C + the
three 2D-RHS compliance entries from S into the 15-element list this
file's consumers share:
c00 c01 c02 c10 c11 c12 c20 c21 c22 c33 c44 c55 s02 s12 s22
where c33/c44/c55 in the output correspond to C(5,5), C(3,3), C(4,4)
— the C++ stress.cc ordering (re-orders shears xy/yz/zx).
::Elastic::transiso_cij
file: TclLib/Models/Elastic.tcl
::Elastic::transiso_cij — transverse-isotropic stiffness from
engineering constants.
Args:
E1, E2 — Young's moduli (1 = out of plane, 2 = in plane)
G12 — Shear modulus in plane containing the 1-axis
v12 — Poisson's ratio for stress-1 / strain-2 coupling
v23 — Poisson's ratio within the isotropic plane
Fixed-orientation contract: the matrix is built with axis-0 = the
symmetry axis (the out-of-plane "1-direction") and axes 1,2 = the
isotropic plane. FLOOXS device convention puts the out-of-plane
direction on device-X, so the matrix is already in device frame —
there is NO orientation parameter. Wire a Bond rotation only after
the matrix is reordered to the (100,010,001) crystal-axis convention.
Returns a 12-element list (no 2D-RHS compliance terms — transverse-iso
decks don't use those entries):
c00 c01 c02 c10 c11 c12 c20 c21 c22 c33 c44 c55
::Generation::Avalanche::vanOberstraeten::__tanh
file: TclLib/Models/Generation/Avalanche.tcl
Internal: hyperbolic tangent as an Alagator expression.
::Generation::B2B::__schenk_kernel
file: TclLib/Models/Generation/B2B.tcl
--- Shared Schenk kernel ---
The three Schenk variants (Schenk / SchenkMultiValley / MultiBandSchenk)
share the n / p / SchenkSRH density-correction expression and the
Fc_pm / Fc_mp / exp-sum body shape. Each variant differs only in:
- how many EgEff terms enter the inner sum (1 vs 6),
- what those EgEff strings look like (literal Eg, EgEff alagator
field, or per-(valley, band) Eg+Delta combinations),
- any auxiliary spec-dict entries that need to ride along (e.g.
SchenkMultiValley's EgEff declaration).
The kernel below absorbs the shared body. N==1 emits the byte-exact
legacy expression (no leading `0+`, no `/N.` divisor). N>1 builds
the parenthesized `(0+term1+...+termN)` sum and divides by N (matches
MultiBandSchenk's legacy `/6.`).
::Hall::lorentz_tensor
file: TclLib/Models/Hall/compose.tcl
::Hall::lorentz_tensor — population × (I + μ_H B×) Lorentz rotation
tensor for the QF continuity wrap. `pop` is the carrier population
symbol (Elec / Hole); `mob` the Hall-mobility symbol (HallEmob /
HallHmob). Single source for the tensor layout — consumed by the
legacy Transport/Hall model and by the Aggregate magnetic-field
branch (which were byte-identical copies).
::HighFieldMobility::schema
file: TclLib/Models/HighFieldMobility/compose.tcl
::HighFieldMobility::schema — model-level key sets for the resolver.
The model slice is role-nested ({electron {…} hole {…}}), so the
schema validates the ROLE keys; the per-role param sets stay in the
Canali builder's pull_check (which also serves the Bands
highfield_mobility path that bypasses the resolver).
::HighFieldMobility::wrap_carrier
file: TclLib/Models/HighFieldMobility/compose.tcl
::HighFieldMobility::wrap_carrier — apply the at-most-one declared
HFM wrap to a low-field μ-string for one carrier.
At-most-one mutex is enforced on `fam_dict`. When the chosen model
doesn't declare the carrier slice, returns `mu_lo` unchanged (the
carrier-blind pass-through contract). When `mu_lo` is "", returns
"" without dispatching (nothing to wrap).
Used by:
- ::Device::HighFieldMobility (called twice; result wraps into the
Emob / Hmob spec-dict overrides).
- ::Bands::__compose_mobility (called once for the band's
quasi_fermi-implied carrier).
Args mirror ::Mobility::compose_carrier: $where defaults to
"HighFieldMobility $mat".
::Mobility::__carrier_slice
file: TclLib/Models/Mobility/compose.tcl
Internal helper: extract a model dict's carrier slice (electron or
hole sub-dict). Returns "" if the carrier isn't declared for this
model.
::Mobility::compose_carrier
file: TclLib/Models/Mobility/compose.tcl
::Mobility::compose_carrier — walk a Mobility-family slice for one
carrier and return the Mathiessen-composed μ-string (or "" when no
declared model produced a contribution).
Dispatch is dictionary-driven: the model name IS the namespace. For
each declared {Model, model_dict} entry the proc probes
`::Mobility::<Model>::<carrier>` via auto-load (high-field saturation
wraps live under HighFieldMobility; piezo/orientation tensors under
ConductivityMultiplier — neither participate at this layer).
Used by:
- ::Device::Mobility (called twice, once per carrier; result wraps
into the Emob / Hmob spec-dict entries).
- ::Bands::__compose_mobility (called once for the band's
quasi_fermi-implied carrier; result is the per-band Mob_<band>).
Args:
mat — material name; first positional arg to each model builder.
carrier — "electron" or "hole".
fam_dict — the {Model { electron {…} hole {…} } …} slice.
T x_expr — temperature and composition fraction (forwarded to builders).
where — error-label prefix; defaults to "Mobility $mat".
::Mobility::Klaassen::__build_dopant
file: TclLib/Models/Mobility/Klaassen.tcl
Internal: build Klaassen mobility for one (material, carrier, dopant)
slice. Used by __build below; returns the per-dopant Alagator string
or "" when the dopant's params are incomplete.
::Mobility::Klaassen::build
file: TclLib/Models/Mobility/Klaassen.tcl
Build full Klaassen mobility for one (material, carrier) — the
`build` entry point every Mobility model exposes (probed by
::Mobility::compose_carrier). Walks the dopants sub-dict, builds
one per-dopant Klaassen expression per fully-declared dopant,
Mathiessen-sums them. Doping / carrier field names are the
canonical Alagator symbols (Accept / Donor / Elec / Hole).
::Permittivity::schema
file: TclLib/Models/Permittivity/compose.tcl
::Permittivity::schema — known/required param sets per model,
consumed by ::Pull::resolve_select_one at slice-materialization time.
::Pull::__has_builder
file: TclLib/Models/Combinators.tcl
::Pull::__has_builder — does proc $qual exist (already defined or
auto-loadable from tclIndex)? Returns 1 if callable, 0 otherwise.
Consolidates the `[info procs $qual] ne "" || [auto_load $qual]` probe
that appeared across the framework (3× inside this file, 3× in
Mobility/compose.tcl's three-shape per-carrier classification).
::Pull::collect_specs
file: TclLib/Models/Combinators.tcl
::Pull::collect_specs — spec-dict-collecting compose over per-model
builders that return `{<spec_dict> <g_keys>}` 2-list pairs.
Generation/B2B's per-model compose procs all return this 2-list:
spec-dict entries to merge into the family's spec-dict, plus a list
of solution names that contribute additively to the family-level G
sum. This helper iterates the fam_dict, dispatches each model, and
accumulates both halves.
Returns `{<merged_spec_dict> <accumulated_g_keys>}`; both empty when
fam_dict is empty. Raises with $where prefix on missing builder.
Args mirror sum_models / select_one.
::Pull::parse_flags
file: TclLib/Models/Combinators.tcl
::Pull::parse_flags — wrapper-level flag-list parser shared by the
`device` and `stress` Tcl wrappers. Iterates the args list (NOT a
string-mapped concat) so brace-quoted values (`pull=$models`, the
`movie={…}` callback) survive intact. Accepts:
`bareword` → value 1
`!bareword` → value 0
`key=value` → value
`key=` `value` → value (split-token form)
Returns a dict. Exact-token matching only — substring forms like
`t.init` cannot false-positive a `init` lookup.
::Pull::resolve_select_one
file: TclLib/Models/Combinators.tcl
::Pull::resolve_select_one — chain-aware select-one resolver.
For mutex (select-one) families, a pure ::Device::resolve_models
deep-merge would combine a parent's model with a child's into one
slice that then trips the mutex check, mangling the obvious "child
overrides parent" intent. This resolver implements the correct
semantics:
1. Closest ancestor with a declaration in $family picks the model.
Each link in the chain is mutex-checked individually.
2. Within that chosen model, params chain-merge per-key (root-
first so the closest descendant wins at leaf level).
Lifted from the former stress-only `__stress_resolve_elasticity`;
parametrized by family name so Permittivity / Quantum / Transport /
Elasticity (and any future select-one family) share one walker.
Optional schema validation: when `schema` is non-empty it's a dict
`{<Model> {known {…} required {…}} …}`. The resolver then validates
at the point the slice is materialized from the chain:
- the chosen model must be a schema key (unknown-model typo)
- every key in every chain link's slice must be in the model's
known set — the error names WHICH ancestor declared the typo
- every required key must be present in the merged params
With schema validation in the resolver, the per-model builders stay
pure expression builders. Empty schema skips all three checks
(device-side selone families validate in their builders today).
Interface materials (`materinterface M1 /M2`) have an empty inherit
chain — fall back to the literal material name so their slices stay
reachable (doc/BOTTOMUP.md §8.4), matching `models_dict_get`.
Args:
models — un-merged per-material dict (the deck-owned `::Models`-
shape value)
mat — material being resolved
family — family name (e.g. Elasticity, Permittivity)
schema — optional per-model {known required} dict (see above)
Returns `{model params}` where `model` is the chosen model name and
`params` is its chain-merged param dict. Returns `{"" {}}` when no
link in the chain declares the family.
::Pull::select_one
file: TclLib/Models/Combinators.tcl
::Pull::select_one — mutex-checked dispatch to at most one model.
Validates that `fam_dict` declares at most one model; raises with
$where prefix on mutex violation. Dispatches to
`::${ns}::${model}::${suffix}` via auto_load probe and returns the
raw model result. When `fam_dict` is empty, dispatches the
`default_model` (with {} params) if non-empty, else returns "".
Used by selector families where the declared model picks a
discretization or a single physical law (Permittivity, Quantum).
Args:
fam_dict — family slice; 0 or 1 model declared
ns, suffix — as above
mat — material name; first positional arg to builder
where — error-label prefix
default_model — fallback model when fam_dict is empty;
"" → return "" (caller decides whether that's OK)
args — extra trailing args after (mat, params)
::Quantum::schema
file: TclLib/Models/Quantum/compose.tcl
::Quantum::schema — known/required param sets per model, consumed by
::Pull::resolve_select_one at slice-materialization time.
::Stress::schema
file: TclLib/Models/StressWrapper.tcl
::Stress::schema — single source of truth for the families stress
pull owns and their declared models. `::Pull::resolve_select_one`
validates every chain link's slice against `known` and the merged
params against `required`. Builders live at
::Elasticity::<Model>::expression and are pure expression builders.
::Transport::schema
file: TclLib/Models/Transport/compose.tcl
::Transport::schema — known/required param sets per model, consumed
by ::Pull::resolve_select_one. QF / Velocity / SG take no params;
Hall requires both factors (a deliberate anisotropy choice needs
both); DPTensor's nested valley_axes sub-dicts validate inside the
builder.
__device_bool
file: TclLib/Models/DeviceWrapper.tcl
Internal helper: boolean flag presence (returns 1 if set to non-zero).
__device_contacts
file: TclLib/Models/DeviceWrapper.tcl
Contact-dispatch loop used by both modes. Per-contact: insulator
(Oxide/SiO2/HfO2) → Gate with the adjacent semiconductor's work
function; semiconductor → mode-specific Ohmic (FEQFOhmic for `feqf`,
SGOhmic for `sg`). FEQF retains the legacy Polysilicon special
case: when the contact has an insulator + Polysilicon stack, emit
Gate with the hardcoded name `gate` and wfn=4.6 instead of dispatching
by adjacent material.
Shared preamble emitted by `device pull` for both FEQF and SG modes.
Stamps the doping aliases, the `d` default, the Silicon/Oxide Dcm
distance field, and the Potential / Circuit / DevPsi solutions that
every contact and per-material composer references.
__device_shared_tail
file: TclLib/Models/DeviceWrapper.tcl
Shared trailing solutions for both modes: scalar E magnitude, the
Silicon Eperp surface-perpendicular field, and the Jn/Jp
current-magnitude solutions. The Temp/T stamp that used to sit
between Eperp and Jn (feqf only, hardcoded 300) moved to the
device_pull preamble, which stamps the actual T= argument for every
mode.
__diffuse_collect_species
file: TclLib/Models/DiffuseWrapper.tcl
Collect every species name declared across every bulk material's
Diffusion slice (excluding the Interfaces sub-family — those write
into existing bulk solutions, not their own unknowns). Returned in
deterministic first-seen order so re-emission is stable.
__diffuse_emit_species_solutions
file: TclLib/Models/DiffuseWrapper.tcl
Auto-emit global `solution add name=$sp solve !damp !negative` for
every declared bulk species. Species like Int/Vac/I2/Boron are
pre-declared in src/FLOOXS.models as `nosolve`; this flip is what
turns them into PDE unknowns. `solution add` is idempotent — the
C-side handler updates flags without re-creating the entry.
__diffuse_emit_temp
file: TclLib/Models/DiffuseWrapper.tcl
Auto-emit a per-material `Temp const val=$T add solve` solution.
Idempotent across materials — only the first material that hits this
helper installs the global Temp; subsequent calls are no-ops.
__diffuse_is_interface
file: TclLib/Models/DiffuseWrapper.tcl
Is $mat an interface material? `materinterface M1 /M2` materials
don't appear in `mater list`; we detect them by the `Mat1_Mat2`
underscore-name pattern AND by checking both halves are declared
materials.
__diffuse_shared_preamble
file: TclLib/Models/DiffuseWrapper.tcl
Shared preamble — `Noni`/`Poni`/`Stress_x`/`Velocity_mag` const
solutions referenced by the rate procs' Alagator expressions.
Idempotent; safe to re-run.
__internal_substrate_fill_lines
file: TclLib/Models/InternalSubstrate.tcl
Internal helper: given a sorted unique list of required positions plus
a target gap, return a denser list with intermediate fill points so
every consecutive pair is within `target`.
arr
file: TclLib/Models/DiffusionHelpers.tcl
Numeric Arrhenius helper: pre * exp(-act / kT). Tcl-time evaluation
(distinct from the Alagator `[Arrhenius {…} …]` literal that DiffLimit /
ConcBind / SurfDiffLimit return). Used by deck-time dict construction
(`dict set ... D0 [arr 0.138 1.37 $kT]`) to compute the numeric value
the Diffusion composer will stamp into the namespace var.
ConcBind
file: TclLib/Models/DiffusionHelpers.tcl
Concentration-binding equilibrium: lattice density × exp(entropy)
× exp(-binding/kT). Returns a `[Arrhenius {…} …]` literal.
device
file: TclLib/Models/DeviceWrapper.tcl
device — TCAD-side wrapper that translates legacy device-command
flag sets into `solve <mode>` calls. Subcommands:
device pull T=… miller=… pull-mode equation setup
device init soft reset + steady solve
device steady solve
device freq=Hz [complex] AC small-signal
device time=s […] transient
device store|restore|clear DC checkpoint primitives
Forwards everything else to `solve` with the appropriate mode.
DiffLimit
file: TclLib/Models/DiffusionHelpers.tcl
Diffusion-limited reaction rate constant for capture of $Species by $Mat.
Returns a literal `[Arrhenius {(4π Σ D0 · Lspa)} barrier]` string.
diffuse
file: TclLib/Models/DiffuseWrapper.tcl
diffuse — Tcl wrapper. Intercepts `diffuse pull` (Tcl-side
equation setup) and forwards every other invocation to the renamed
C command via `tailcall` so the wrapper's frame is gone before the
C runs. See cov_complex_newton history for why bog-standard
`uplevel 1` doesn't work for the non-pull path: the wrapper's
leftover proc frame interferes with the C-side internal Tcl_Eval
sequence (`solution name=Temp …` → `diffstep …`).
diffuse_pull
file: TclLib/Models/DiffuseWrapper.tcl
diffuse pull — pull-mode equation setup.
Walks `mater list` and dispatches each material's `::Models <Mat>
Diffusion` dict slice through the per-sub-family composers in
TclLib/Models/Diffusion/. Interface materials (not in `mater list`)
are dispatched in a second phase.
Per-material baseline.tcl files (TclLib/Device/<Mat>/baseline.tcl)
are auto-sourced by `::Defaults::diffuse` when called bareword.
init_adapt_fields
file: TclLib/Models/AdaptFields.tcl
Substeps 3a + 3b fields. Additional Grid.* fields are added by later
Phase-3 substeps (ShrinkEarly, ShrinkLate, GridAddPerp, Refine.Stop, ...).
perp.add.dist / Max.Radius / bound.add.dist / Corner.Add are only read by
the growing-mesh GridAdd path (LCOV_EXCL'd in coverage today, since the
active deposit goes through DepLvl which calls GridUpd(do_add=0)).
Defaults track the historical 0.1*UnitScl values; decks override with
`sel z=<expr>*Mater(SomeMat) ...` for per-material scoping.
MatBandGap
file: TclLib/Models/MatAccessors.tcl
Build the Varshni temperature-dependent bandgap expression for a
material. Returns an Alagator string Eg0 - α·T² / (T+β) safe to
embed in `solution add name=Eg val=…`. Used by the per-material
`<Mat>::BandGap` accessor shims.
MatNcTotal
file: TclLib/Models/MatAccessors.tcl
Material-effective Nc: Σ over all declared conduction valleys of
`BandEdgeNumberOfStates T= m=(ml·mt²)^(1/3)`. Useful for decks /
tests that want a single per-material Nc rather than the per-valley
decomposition the dispatcher emits.
MatNvTotal
file: TclLib/Models/MatAccessors.tcl
Material-effective Nv: Σ over all declared hole bands of
`BandEdgeNumberOfStates T= m=<band m>`.
NB: ValenceBands `m` values are stored PRE-RAISED to the 3/2 power
(BandEdgeNumberOfStates' m-slot convention — Si LH 0.1737 ≈
0.31^{3/2}), so they pass through verbatim. Conduction valleys
store raw ml/mt and go through ::Device::dos_m32 instead.
matparam_proc
file: TclLib/Models/Matparam.tcl
matparam_proc — chain-walking proc resolver.
Symmetric to matparam (which walks the chain for data) — walks the inherit
chain looking for a proc named ::<link>::<proc_name> and returns its fully
qualified name (e.g. ::Silicon::Nc). Returns "" if no link in the chain
defines the proc. Forces auto_load on each candidate before testing
existence so a chain link whose source file hasn't loaded yet still
resolves.
Used by the Transport/DPTensor and BandStructure/StrainKP composers to
resolve per-material accessor procs (Nc, Nv, Get3DElecDPTensor,
Get3DElecDPTensorPiezoHall, ElecHallFactorTemp) — a child material
inheriting Silicon picks up Silicon's accessors automatically, no
per-variant proc required. These accessors are the transitional
bridge to dict slices (see CLAUDE.md "Composer-internal per-material
accessors").
matparam_sub
file: TclLib/Models/Matparam.tcl
Same shape but for nested per-species namespaces. Used by chemistry:
parameters live at ::<mat>::<sub>::<key> where <sub> is the species name.
Example: matparam_sub Silicon Smic Bind => $::Silicon::Smic::Bind.
matparam_sub3
file: TclLib/Models/Matparam.tcl
Four-deep variant: ::<mat>::<sub>::<def>::<key>. Used by the dopant library
where per-(dopant, defect) params live at ::<Mat>::<Dopant>::<Defect>::<Key>
(e.g. ::Silicon::Boron::Int::Binding). Closes the gap left by Dopant.tcl's
dopant_has2 / dopant_get2 helpers, which read the literal 4-deep namespace
without walking the inherit chain — meaning a SiGe-derived deck couldn't
inherit Silicon's per-(dopant, defect) params without redeclaring them all.
models_dict_get
file: TclLib/Models/Matparam.tcl
models_dict_get — chain-walking dict accessor.
Walks `mater name=$mat chain` and returns the dict slice at the given
path for the FIRST chain link that has it. Returns "" when no link
has the path. Canonical chain-walk for `device pull=…` and `stress
pull=…` callers that own their dict locally.
Examples (assuming SiGech inherits Silicon):
dict set models Silicon Elasticity Anisotropic {C11 165.6e10 ...}
models_dict_get $models SiGech Elasticity ;# → {Anisotropic {C11 165.6e10 ...}}
models_dict_get $models SiGech Elasticity Anisotropic C11 ;# → 165.6e10
models_dict_get $models Polysilicon Elasticity ;# → ""
pde_append
file: TclLib/Models/PdeAccumulator.tcl
---- APPEND (cross-coupling fragment) ----
The fragment is expected to be sign-prefixed: "+ X" / "- Y". Empty-slot
semantics: store as "0 fragment" so the equation parses cleanly even before
the self-contribution is added.
pde_flush
file: TclLib/Models/PdeAccumulator.tcl
---- FLUSH ----
Emits one `solution <Mat> name=<Sol> pde value="<accumulator>"` per
populated slot. With -mater <Mat>, restricts emission to that material.
The flush is a side-effect — it doesn't clear the accumulator (use
pde_init * * if you want to wipe).
pde_init
file: TclLib/Models/PdeAccumulator.tcl
---- INIT ----
pde_keys
file: TclLib/Models/PdeAccumulator.tcl
Return all (Mat, Sol) keys currently in the accumulator.
pde_peek
file: TclLib/Models/PdeAccumulator.tcl
---- inspection helpers ----
pde_set_self
file: TclLib/Models/PdeAccumulator.tcl
---- SET_SELF (own bulk contribution, idempotent across rebuild passes) ----
pull_check
file: TclLib/Models/Combinators.tcl
pull_check — strict-consumption + required-present check.
Pull-mode model procs all open with the same preamble:
- validate that every key in $params is in the known set (typo
guard)
- check that every required key is present; if not, the model
drops out (additive sites return "", wrapper sites return the
pass-through input)
This helper collapses that preamble. Returns 1 when every required
key is present, 0 otherwise. Raises with $where as the message
prefix when params contains an unknown key.
Usage:
if { ![pull_check $params {a b c d} {a b c} "Family/Model $mat $role"] } {
return "" ;# additive
return $mu ;# wrapper
}
set a [dict get $params a]; …
One pattern the helper does NOT cover:
- "missing required → error" sites (e.g. Transport/Hall must have
factor_e + factor_h). Those call pull_check and then raise
explicitly on the 0 return.
Select-one families that need per-chain-link validation (Elasticity)
pass a schema to ::Pull::resolve_select_one instead — validation
happens where the slice is materialized from the chain.
pull_check_all
file: TclLib/Models/Combinators.tcl
Ergonomic shortcuts for the two pull_check shapes that dominate the
per-model builders:
pull_check_all $params $known $where → pull_check $params $known $known $where
every key in $known is required; missing → drop the model
pull_check_known $params $known $where → pull_check $params $known {} $where
every key in $known is optional; never drops the model,
just enforces typo guard
Partial-required sites (where required ⊊ known — e.g. Klaassen's `NrefD`
is optional within an otherwise-required set) keep the explicit
three-argument `pull_check` form.
spec_const
file: TclLib/Models/Render.tcl
Spec-dict constructors — every model proc that returns a spec-dict uses
these instead of the verbatim `[dict create kind <K> flags <F> val <V>]`
literal. Keeps the spec-dict shape in one place; gives `Render.tcl` the
single seam to extend (e.g. the `kind snap` shape for `sel z=` snapshots).
`spec_const $val` → const-solvesolution (the most common form).
`spec_const $val $flag_list` → const with explicit flag list.
`spec_pde $val` → pde-solvesolution.
`spec_pde $val $flag_list` → pde with explicit flag list.
spec_snap
file: TclLib/Models/Render.tcl
`kind snap` emits a `sel z= <val> name= <name>` snapshot instead of a
`solution add` — used when the field must be a Jacobian-isolated
instantaneous value, not a const-solvesolution whose Jacobian would
propagate through downstream assembly (the canonical use is the
DPTensor model's HallMob = r*Emob snapshot, which would otherwise
diverge the PiezoHall breakdown test by ~200×).
spec_snap_init
file: TclLib/Models/Render.tcl
`kind snap_init` is the guarded variant: the snapshot stamps only
when the field doesn't already exist (DataExists). Used for
zero-initializing strain / stress / B scratch fields without
clobbering pre-stamped data (e.g. a stress solve that ran before
`device pull`). Plain `snap` stays unguarded — HallMob must
re-evaluate on every pull.
stress
file: TclLib/Models/StressWrapper.tcl
stress — elastic equation compile (`pull` / `pull=$dict`) and Newton
solve (`calcstress` / `!calcstress`). See file header for the
validation / inheritance semantics.
SurfDiffLimit
file: TclLib/Models/DiffusionHelpers.tcl
Surface diffusion-limited rate at a Mat/Side interface. Uses Side's D0 +
Lspa and Mat's KinkSite.
voigt_components
file: TclLib/Models/Elastic.tcl
voigt_components — canonical six-component Voigt sequence used by every
stress-side consumer that iterates strain/stress components. Ordering
is load-bearing for UniformStress / StressFromStrain (compliance-matrix
matvec depends on it); other consumers (e.g. the `stress pull` field
preamble) only need the six component labels and any order would work,
but they call this proc anyway so the labels never drift out of sync.