FLOOXS » TclLib » Models

Models — TclLib Procs

80 documented proc(s) in TclLib/Models/.

::BandStructure::__assign_family_shifts · ::BandStructure::__compose_flat · ::BandStructure::__compose_multivalley · ::BandStructure::__hole_solution_name · ::BandStructure::__lowest_affinity · ::Defaults::device · ::Defaults::register · ::Defaults::stress · ::Device::__append_flag_token · ::Device::__flag_present · ::Device::__render_const · ::Device::__render_pde · ::Device::assert_consumed · ::Device::consume · ::Device::dict_deep_merge · ::Device::is_dict · ::Device::render · ::Device::resolve_models · ::Elasticity::__pde_expr · ::Elasticity::__strain_tuple_3d · ::Elasticity::__stress_tuple · ::Generation::Avalanche::vanOberstraeten::__tanh · ::Generation::B2B::__schenk_kernel · ::Mobility::__carrier_slice · ::Mobility::Farahmand::hole · ::Mobility::Kanda::__wrap · ::Mobility::Klaassen::__build · ::Mobility::Klaassen::__build_dopant · ::Pull::__has_builder · ::Pull::collect_specs · ::Pull::resolve_select_one · ::Pull::select_one · __cubic_stiffness · __device_bool · __device_contacts · __device_feqf_continuity · __device_get · __device_parse_args · __device_sg_continuity · __device_shared_preamble · __device_shared_tail · __internal_substrate_fill_lines · __pack_aniso_result · __stress_parse_args · __stress_preamble · __stress_pull_impl · arr · build_chemistry · cij_atensor · cij_stensor · clear_chemistry · ConcBind · device · DiffLimit · init_adapt_fields · MatBandGap · MatNcTotal · MatNvTotal · matparam_proc · matparam_sub · matparam_sub3 · models_assert_empty · models_consume · models_dict_get · pde_append · pde_flush · pde_init · pde_keys · pde_peek · pde_set_self · pull_check · pull_check_all · pull_check_chain · pull_check_required · set_aniso_elastic · set_transverse_iso_elastic · spec_const · spec_snap · stress · SurfDiffLimit

::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::__lowest_affinity

file: TclLib/Models/BandStructure/compose.tcl

Compute χ_lowest = max(χ_v) across all valleys, as a nested-ternary
Alagator expression.  Deduplicates identical χ's so a 6-valley
X-only material with shared χ produces a trivial constant.

::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::register

file: TclLib/Models/Defaults.tcl

::Defaults::register <mat> <full_dict>

Splits a material's full physics dict by family name into stress-
domain and device-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::__append_flag_token

file: TclLib/Models/Render.tcl

Internal: append a flag token to the tokens list, handling
`dampval=<v>` and bare keyword forms.

::Device::__flag_present

file: TclLib/Models/Render.tcl

Internal: does a flag (literal token) appear in the flags list?

::Device::__render_const

file: TclLib/Models/Render.tcl

::Device::__render_const — emit a `solution $mat add name=$name const
<flags> val=$val` call.

::Device::__render_pde

file: TclLib/Models/Render.tcl

::Device::__render_pde — emit a `solution $mat add name=$name pde
<flags> val=$val` call.

::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::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::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.

::Elasticity::__pde_expr

file: TclLib/Models/Elasticity/compose.tcl

Canonical displacement-PDE Alagator shape: every elasticity model
emits T·elastic(u) + T·strain(...) + stress(...).  Only T and the
strain pre-factors differ per model / per dim.

::Elasticity::__strain_tuple_3d

file: TclLib/Models/Elasticity/compose.tcl

3D strain field tuple (six components, three diagonal + three shear
zeros).  2D builders supply their own tuple inline because the
pre-factors (1.0+pr for Iso, 1-s02/s22 for Aniso) differ — there is
no 2D form here.

::Elasticity::__stress_tuple

file: TclLib/Models/Elasticity/compose.tcl

2D vs 3D stress field tuple.

::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.`).

::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::Farahmand::hole

file: TclLib/Models/Mobility/Farahmand.tcl

Farahmand is electron-only.  Hole mobility for III-N materials is
typically a scalar — declared via Mobility { Constant { hole { mu <v> } } }
alongside Farahmand's electron entry.

::Mobility::Kanda::__wrap

file: TclLib/Models/Mobility/Kanda.tcl

Internal: build the Kanda per-axis wrap for one carrier.  `base_mu`
is the upstream scalar mobility expression (output of Mathiessen
sum + any prior wraps like Canali).

::Mobility::Klaassen::__build

file: TclLib/Models/Mobility/Klaassen.tcl

Internal: build full Klaassen mobility for one (material, carrier).
Walks the dopants sub-dict, builds one per-dopant Klaassen expression
per fully-declared dopant, Mathiessen-sums them.

::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.

::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::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.

Args:
  models    — un-merged per-material dict (the deck-owned `::Models`-
              shape value)
  mat       — material being resolved
  family    — family name (e.g. Elasticity, Permittivity)

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)

__cubic_stiffness

file: TclLib/Models/Elastic.tcl

Cubic 6x6 stiffness matrix in crystal frame from C11, C12, C44.

__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.

__device_feqf_continuity

file: TclLib/Models/DeviceWrapper.tcl

FEQF-mode carrier-shape continuity solutions: Lambda + Qfn/Qfp PDEs
+ scalar Emfn/Emfp from quasi-Fermi gradients.

__device_get

file: TclLib/Models/DeviceWrapper.tcl

Internal helper: pull a flag value from the parsed dict, with default.

__device_parse_args

file: TclLib/Models/DeviceWrapper.tcl

Internal: parse a device-style args list into a dict of (flag, value).
  `bareword`     → value 1
  `!bareword`    → value 0
  `key=value`    → value
  `key=`  `value`→ value   (split-token form, used in legacy code)

Exact-token matching only — no substring false positives from `t.init`
masquerading as `init`.  Iterate the list directly without string
mapping so brace-quoted values (movie={...long Tcl callback...})
preserve their grouping semantics.

__device_sg_continuity

file: TclLib/Models/DeviceWrapper.tcl

SG-mode carrier-shape continuity solutions: Elec/Hole PDEs + Qfn/Qfp
const + per-axis Emfn{x,y,z}/Emfp{x,y,z} field-magnitude solutions.

__device_shared_preamble

file: TclLib/Models/DeviceWrapper.tcl

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, the FEQF-only Temp/T
alias, and the Jn/Jp current-magnitude solutions.  Order matters —
the legacy FEQF emitter ran Temp BETWEEN Eperp and Jn, so the mode
arg gates Temp at the right position.

__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`.

__pack_aniso_result

file: TclLib/Models/Elastic.tcl

Pack a rotated 6x6 stiffness matrix + the three 2D-RHS compliance entries
into the 15-element list expected by cij_atensor / cij_stensor:
  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).

__stress_parse_args

file: TclLib/Models/StressWrapper.tcl

Internal flag parser: iterates the args list so brace-quoted values
(including whole dicts substituted via `$models`) survive intact.

__stress_preamble

file: TclLib/Models/StressWrapper.tcl

__stress_preamble — Elasticity-family field/global-solution setup
that the per-material composer's PDE references.  Idempotent.

Family-level rather than dispatcher-level: this is the equivalent
of the device side's `__device_shared_preamble` — fields and
global solutions shared across every material that participates in
the family.  Lifted out of `__stress_pull_impl` so a future second
stress family (e.g., Thermal) gets its own preamble proc without
the wrapper growing inline blocks.

__stress_pull_impl

file: TclLib/Models/StressWrapper.tcl

__stress_pull_impl — drives the pull-mode Elasticity dispatch over
`mater list`, using the shared framework primitives:
  ::Pull::resolve_select_one — chain-aware select-one resolver
  ::Stress::Elasticity        — pure-function family composer
  ::Device::render            — single `solution add` emission sink
  ::Device::assert_consumed   — leftover-family diagnostic

Caller's $models is read but never mutated.  Per-iteration leftover
check catches "deck passed a dict with non-Elasticity families"
(e.g., the unfiltered ::Models or `::Defaults::device`).

arr

file: TclLib/Models/ChemistryHelpers.tcl

Numeric Arrhenius helper: pre * exp(-act / kT).  Tcl-time evaluation
(distinct from the Alagator `[Arrhenius {…} …]` literal that DiffLimit /
ConcBind / SurfDiffLimit return).  Used by the dopant param declarers
in TclLib/Device/Silicon/Dopants/Params/ to replace the per-file
`proc _Arr` + `rename _Arr ""` workaround.

build_chemistry

file: TclLib/Models/ChemistryPackage.tcl

Three-phase build driver.  With -mater Mat, restricts phases 1+2 to
(Mat, Sol) registrations for that material AND the flush to that material
too.  Without it, runs everything.

cij_atensor

file: TclLib/Models/Elastic.tcl

Full anisotropic ATensor: twelve independent constants from the rotated
6x6 stiffness matrix.

cij_stensor

file: TclLib/Models/Elastic.tcl

Isotropic-by-symmetry STensor: three independent constants
c00 (longitudinal), c01 (off-diagonal), c22 (shear). Takes the full
15- or 12-element list returned by set_aniso_elastic; ignores all but
the relevant entries.

clear_chemistry

file: TclLib/Models/ChemistryPackage.tcl

Remove all chemistry registrations.  Useful at the start of a deck that
wants a clean slate.

ConcBind

file: TclLib/Models/ChemistryHelpers.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/ChemistryHelpers.tcl

Diffusion-limited reaction rate constant for capture of $Species by $Mat.
Returns a literal `[Arrhenius {(4π Σ D0 · Lspa)} barrier]` string.

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>`.

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::ConductionTensorHook).  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 DriftDiffusionPackage dispatcher so a child material
inheriting Silicon picks up Silicon's ConductionTensorHook /
ValenceTensorHook / ValenceStrainHook automatically — no per-variant
proc required.

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_assert_empty

file: TclLib/Models/Matparam.tcl

models_assert_empty — error if the dict has any non-empty material
entries.  Names every leftover (material, family, …) path so a deck
author can fix the typo / unused declaration that survived dispatch.

models_consume

file: TclLib/Models/Matparam.tcl

models_consume — remove a consumed family from the caller's dict and
collapse the material entry if it has no other families left.
Called by composers after a successful family dispatch; the var name
is passed by the caller, we upvar to mutate.

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]; …

Two patterns 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.
  - Per-chain-link strict consumption (Elasticity).  Those walk the
    inherit chain and validate each link's slice — different shape.

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.

pull_check_chain

file: TclLib/Models/Combinators.tcl

pull_check_chain — per-chain-link strict consumption.

Walks the inherit chain of $mat and validates each link's slice at
the path `$models <link> {*}$args` against $known.  Pinpoints WHICH
link in the chain has the offending key — error message names the
link, not the queried child.

Companion to `pull_check`.  Use this when the merged-slice diagnostic
would lose useful information about which ancestor declared the typo
(today: stress Elasticity, where the test deck encodes a
Silicon-typo-caught-when-dispatching-SiGech case).  Most families
don't need this — `pull_check` on the merged slice is sufficient.

Signature mirrors `models_dict_get`: trailing $args is the dict path.
Returns nothing on success; raises with $where and the offending link
name on first unknown key.

pull_check_required

file: TclLib/Models/Combinators.tcl

pull_check_required — chain-aware strict consumption + hard error
on missing required keys.

The shape used by mutex (select-one) family builders that cannot
gracefully degrade — once the dispatcher has picked them, every
required param must be present somewhere in the inherit chain or the
expression cannot be built.

Combines:
  1. Per-chain-link strict consumption (pull_check_chain) — pinpoints
     which ancestor declared an unknown key.  Skipped when $models is
     "" (direct-call sites with a single-link slice).
  2. Merged-slice typo guard (pull_check with empty required).
  3. Required-present check — raises with $where naming the missing
     key when any required key is absent from the merged $params.

Three Elasticity builders (Anisotropic, Isotropic, TransIso) collapse
their identical 13-line prologue to one call.

Args mirror pull_check_chain + pull_check:
  models    — un-merged per-material dict (or "" to skip chain walk)
  mat       — queried material (used in error messages)
  params    — merged effective slice
  known     — every key that may appear
  required  — keys that must be present
  where     — error-label prefix (e.g. "Elasticity/Anisotropic")
  family    — family name for pull_check_chain path
  model     — model name for pull_check_chain path

set_aniso_elastic

file: TclLib/Models/Elastic.tcl

Rotated cubic stiffness for an arbitrary Miller orientation.

Usage:
  set cij [set_aniso_elastic C11=... C12=... C44=... Miller=(hkl)<uvw>]

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 a 15-element list (see __pack_aniso_result above) that the
cij_get/cij_atensor helpers consume.

set_transverse_iso_elastic

file: TclLib/Models/Elastic.tcl

Rotated transverse-isotropic stiffness from engineering constants.

Usage:
  set cij [set_transverse_iso_elastic E1=... E2=... v12=... v23=... G12=...]

Args:
  E1, E2 — Young's moduli (1 = out of plane, 2 = in plane)
  v12    — Poisson's ratio for stress-1 / strain-2 coupling
  v23    — Poisson's ratio within the isotropic plane
  G12    — Shear modulus in plane containing the 1-axis
  Miller — orientation (hkl)<uvw>; default (001)<100>

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

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-solve solution (the most common form).
`spec_const $val $flag_list`   → const with explicit flag list.
`spec_pde   $val`              → pde-solve solution.
`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-solve solution 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×).

stress

file: TclLib/Models/StressWrapper.tcl

stress — elastic equation setup + Newton solve.  See file header.

SurfDiffLimit

file: TclLib/Models/ChemistryHelpers.tcl

Surface diffusion-limited rate at a Mat/Side interface.  Uses Side's D0 +
Lspa and Mat's KinkSite.