::$
Install __declare and __resync procs.
FLOOXS » TclLib » Models
89 documented proc(s) in TclLib/Models/.
::$ · ::$ · ::Generation::Avalanche::vanOberstraeten::__tanh · ::Mobility::Klaassen::__build · ::Mobility::Klaassen::__build_dopant · __bs_has_composition_rule · __compose_bandstructure · __compose_bgn · __compose_dielectric · __compose_drift_diffusion · __compose_elasticity · __compose_elasticity_select · __compose_generation · __compose_mobility_carrier · __compose_permittivity · __compose_quantum · __compose_recombination_terms · __compose_transport · __cubic_stiffness · __dd_all_valleys_have_affinity · __dd_assign_family_shifts · __dd_chain_load · __dd_compute_lowest_affinity · __dd_emit_qfn_continuity · __dd_hole_solution_name · __dd_hydrostatic_shift · __dd_l_dir_index · __dd_multi_valley_ni · __dd_proc_available · __dd_transport_declared · __dd_valley_dg_inv_mass · __dd_x_dir_index · __device_bool · __device_get · __device_parse_args · __internal_substrate_fill_lines · __mobility_parse_carrier_body · __pack_aniso_result · __recombgen_parse_body · __stress_parse_args · __transport_parse_body · __valley_parse_body · arr · build_chemistry · cij_atensor · cij_get · cij_stensor · clear_chemistry · compose_eval_rule · compose_render_value · compose_set_line · ConcBind · device · DiffLimit · DriftDiffusionPackage · elastic_init · elastic_variant · init_adapt_fields · MasettiMobility · MatBandGap · MatNcTotal · MatNvTotal · MatOldSlotboom · matparam_proc · matparam_sub · matparam_sub3 · MatSlotboom · mobility_param · pde_append · pde_flush · pde_init · pde_keys · pde_peek · pde_set_self · register_farahmand_mobility · set_aniso_elastic · set_transverse_iso_elastic · stress · stress_canonical_variants · stress_eq_aniso · stress_eq_aniso_2d · stress_eq_aniso_3d · stress_eq_iso_2d · stress_eq_iso_3d · stress_eq_transiso_3d · stress_known_bases · stress_pull · stress_resolve_base · SurfDiffLimit
Install __declare and __resync procs.
`<Mat>::ElasticInit` is the auto-load trigger that StressPackage's `stress_known_bases` scan finds in auto_index. Emitted dynamically so the per-material file stays data + one declarator line.
Internal: hyperbolic tangent as an Alagator expression.
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.
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.
Internal: detect any value in the BandStructure sub-dict that is a
composition-rule list (`{linear A B}`, `{linear_bowing …}`,
`{linear_neg A B}`). Used by the dispatcher to require an `x` key
when rules are declared.
BandStructure: dispatches Varshni (returns Eg expression) and
pre-stamps per-valley / per-band namespace vars from Valleys /
ValenceBands sub-dicts. Composition rules in dict values (e.g.
`ml { linear 0.20 0.40 }`) are evaluated via ::Compose::eval_value
using the material's top-level `x` dict key.
Returns a dict:
{ eg_expr <Alagator-string|""> nc_distribute <mode|""> }
Side effect: stamps ::<Mat>::ConductionValleys / ValenceBands lists
and ::<Mat>::Conduction::<v>::* / Valence::<b>::* namespace vars.
BGN: Additive sum across declared models. Returns "" if nothing contributes — caller skips the BgnCorrection stamp.
__compose_dielectric <Mat> Stub — Phase E targets DD-only dispatch. Dielectric materials still go through DielectricEqns via the legacy data-shape fallback in device_pull. Phase E' or later will migrate dielectrics to a flat `Permittivity` family in the dict.
__compose_drift_diffusion <Mat> <T> <miller> Walks ::Models <Mat>, composes per-family expressions, pre-stamps matparam keys, hands off to the legacy DriftDiffusionPackage emitter. Caller (device_pull) is responsible for the surrounding __resync / __postdd hook firing.
__compose_elasticity <Mat> Walks ::Models <Mat> Elasticity, dispatches to the per-model builder, pre-stamps the matparam keys the legacy `::ElasticEqns` dispatcher reads. Caller (stress_pull) handles surrounding StressPackage / mater-walk semantics.
Per-family composer for Elasticity. At-most-one model per material (Aniso XOR Iso). Returns the chosen model's info dict.
Generation: dispatch each declared source to its model builder.
Returns a dict:
{avalanche_h <expr>|"" avalanche_e <expr>|"" b2b <list-of-expr>}
The dispatcher uses this to stamp Avah / Avae / Ava (combined with
carrier currents in the legacy Ava formula) and the named B2B sources.
The Generation sub-dict shape:
{ Avalanche { vanOberstraeten {al_h … al_e … …} <Inst2> {…} … }
B2B { Schenk {A B hw} MultiBandSchenk {A B hw} SimpleE1 {A B}
SimpleE1_5 {A B} } }
Mobility: dispatch each declared model to its builder, Mathiessen the additives, Wrap the saturation/surface wrappers. Returns the composed Alagator string for one carrier (electron|hole). Errors when no model declares the carrier with valid params.
Permittivity: single static-er selector (today). Composer returns the scalar `er` value used by the Poisson PDE (semiconductor) or the Laplace PDE (pure dielectric). At-most-one Permittivity model per material; Static is the only choice right now.
Quantum: at-most-one quantum-correction model per material. Today only DG is supported (PoissonSchrodinger is a separate solver path and deferred). Returns the chosen model's info dict.
Recombination: dispatch each model to its instance-stacking builder, return list of (model_name, val) pairs for the dispatcher to stamp into ::<Mat>::RecombinationModels + ::<Mat>::Recombination::<Model>::val.
Transport: at-most-one model declared. Returns the per-model info
dict {form QF|Velocity|SG|Hall, ...}. Empty family / no declaration
→ default QF.
Cubic 6x6 stiffness matrix in crystal frame from C11, C12, C44.
Affinity-mode detection: every conduction valley must have an Affinity key declared. Returns 1 if all do, 0 otherwise. Used at the top of DriftDiffusionPackage step 2 to switch between affinity-derived and legacy-Offset positioning of valleys.
Compute per-valley Shift expressions for one family. Stores into the upvar'd `shifts` array keyed by valley name.
Chain-load every ancestor's <link>::Eqns so its top-level valley / hole_band declarations execute before reads.
Build the alagator expression for `χ_lowest = max(χ_v for v in valleys)`. Electron affinity convention: χ = energy below vacuum, so LARGER affinity means LOWER (more tightly-bound) energy. The lowest conduction band is the one with the maximum χ. Deduplicates identical affinity expressions so a 6-valley material with one shared χ produces a trivial constant, not a 6-deep nested ternary. Multi-distinct-χ materials (SiGe X/L/Γ) get a nested ternary chain.
Default per-QF electron continuity PDE. One PDE per distinct QuasiFermi declared across the valley list. Builds the Velocity term as a sum-of-per-valley-currents weighted by each valley's mass-driven mobility ratio — but for the dispatcher's scalar-Emob path we use the total Elec; per-valley current weighting belongs in a ConductionTensorHook.
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.
Hydrostatic strain shift for Γ-valley. Approximate: tr(strain) scaled by a deformation potential constant. Materials wanting their own Γ shift can override via per-material code; this is the default.
L-valley Dir → index in the LBandEdgeShiftStrain return list.
Order: {111} {-1 1 1} {1 -1 1} {1 1 -1}
Multi-valley intrinsic carrier concentration:
ni = sqrt(Σ_v Nc_v · exp(-(Eg + DeltaE_v) / 2kT)
· Σ_b Nv_b · exp(-(Eg - DeltaE_b) / 2kT))
True if `name` resolves to a callable proc — either already loaded or available via auto_index. Forces auto_load on a hit so the subsequent invocation finds it.
Transport declarer dispatch — used by step 6 / step 12 to detect a
`transport $Mat { … }` block (stored as ::<Mat>::Transport_<Key>) and
emit the conduction / valence current + PDE skeleton. Replaces the
per-material Conduction/ValenceTensorHook bodies that hand-stamped
the same Jnx/Jny/Jnz + Velocity-Qfn pattern across Germanium, SiGe,
and any future material with the same transport shape.
DG inverse mass expression for one valley. Axis-aligned `Dir` aligns
ml on that axis; diagonal {111}-family and Γ ({0 0 0}) use the
isotropic average mDG = (ml + 2*mt) / 3.
X-valley Dir → index in the XBandEdgeShiftStrain return list.
Internal helper: boolean flag presence (returns 1 if set to non-zero).
Internal helper: pull a flag value from the parsed dict, with default.
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.
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`.
Internal: parse a carrier sub-body (a Tcl dict-like list of Key Value pairs) and store each value at ::<mat>::Mobility::<model>::<carrier> ::<key>. uplevel_depth identifies the original caller of mobility_model so $T etc. resolve in the deck.
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).
Internal: parse a body of "Key Value" lines and store each value at ::<mat>::<axis>::<name>::<key>. uplevel_depth tells how many frames up to evaluate the value in (1 = caller of recombination / generation).
Internal flag parser: same logic as DeviceWrapper's parser but stress only has one bareword flag (`calcstress` / `!calcstress`). Iterate the args list directly so brace-quoted values survive.
Body parser: same shape as species / valley / recombination — one "Key Value" line at a time, evaluated in the caller's frame.
Internal: parse a body of "Key Value" lines and store each value at ::<mat>::<axis>::<name>::<key>. uplevel-depth tells how many frames up to evaluate the value in (1 = caller of valley/hole_band).
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.
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.
Full anisotropic ATensor: twelve independent constants from the rotated 6x6 stiffness matrix.
Look up the stiffness list for a material. Tries (in order): literal name, lowercased name, and then the `mater get.inherit` chain — so a material declared `mater name=backsideSi add inherit=Silicon` picks up Silicon's stiffness without an explicit duplicate registration. Errors loudly when nothing is found (silent zeros would mask a broken stress solve).
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.
Remove all chemistry registrations. Useful at the start of a deck that wants a clean slate.
Internal: render a rule expression with the composition placeholder embedded as `$x` (literal — the synthesized __declare proc binds x as its argument so Tcl interpolates it at re-stamp time).
Internal: distinguish a rule (first element is a recognized rule keyword) from a literal value. Literal values are stored as-is.
Internal: convert a `set` value into the line that re-stamps a namespace var. Rule-rendered expressions need double quotes so $x interpolates at proc-call time; literals can use a brace-quoted value to avoid surprise substitution.
Concentration-binding equilibrium: lattice density × exp(entropy) × exp(-binding/kT). Returns a `[Arrhenius {…} …]` literal.
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.
Diffusion-limited reaction rate constant for capture of $Species by $Mat. Returns a literal `[Arrhenius {(4π Σ D0 · Lspa)} barrier]` string.
---------------- Top-level dispatcher ----------------
Generic elastic_init: declare $mat (with its parent chain) if not already in `mater list`. Walks $::Elastic::ParentOf upward until it hits a root (parent == ""). Idempotent — a re-call on an already- declared material is a no-op. If a chain link hasn't been sourced yet, auto-load its ElasticInit (which sources its ElasticEquations.tcl and registers via `elastic_base`). This is what makes a chain like Oxide → BaseMat work when Oxide's file is loaded first.
Register a deck-level variant material that inherits elastic data from a base. `<variant>` doesn't get added to `mater list` here — that happens in StressPackage's stress_canonical_variants after all parents have been initialized. This is the bottom-up replacement for the hardcoded variant→parent table that used to live in StressPackage.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.
MasettiMobility — generic Masetti-form low-field majority mobility.
Reads per-(material, carrier) coefficients declared via the
`mobility_model` declarer (TclLib/Models/MobilityDecl.tcl). Storage
is at ::<Mat>::Mobility::Masetti::<carrier>::<key>, walked via
mobility_param so a child material inheriting Silicon picks up
Silicon's Masetti numbers automatically.
Carrier ∈ {electron, hole}. Returns an Alagator expression for the
named carrier's bulk mobility.
Unified Masetti form (both electron and hole — set Pc=0 for electron
to eliminate the umin1*exp(-Pc/N) prefactor that's hole-only in the
canonical Sentaurus Masetti definition):
mu = umin1 * exp(-Pc / N)
+ (uconst - umin2) / (1 + (N / Cr)^alpha)
- u1 / (1 + (Cs / N)^beta)
where N = abs(Donor) + abs(Accept). `uconst` is typically a
temperature-dependent expression like "1417*(Temp/300)^(-2.5)" using
the Alagator field name `Temp` as the placeholder. Callers passing
T=<value> get a string-map remap from `Temp` to that value (so legacy
callers passing T=300 still produce a fully numeric expression).
Build the Varshni temperature-dependent bandgap expression from a material's stored VarshniEg0 / VarshniAlpha / VarshniBeta values. Returns an alagator string; safe to embed in `solution add name=Eg val=...`. Used both by the dispatcher (step 2) and by the per- material BandGap thin shims kept for backward compatibility with decks that read Eg(T) directly.
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.
Material-effective Nv: Σ over all declared hole bands of `BandEdgeNumberOfStates T= m=<band m>`.
Convenience shorthand for the OldSlotboom variant — same shape as MatSlotboom but pulls the OldSlotboom* keys.
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.
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.
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.
Generic Slotboom bandgap-narrowing dispatcher. Pulls per-material Ebgn / Nref via matparam, then returns the standard Ebgn * ( log(N/Nref) + sqrt(log(N/Nref)^2 + 0.5) ) alagator string with N = Accept + Donor. Used by per-material Slotboom / OldSlotboom shims so the formula lives in one place. Keys consumed (per material, via matparam chain walk): key=SlotboomEbgn / SlotboomNref (default model — call as `MatSlotboom mat=<X>`) key=OldSlotboomEbgn / OldSlotboomNref (legacy model — set key= manually or use MatOldSlotboom shorthand)
mobility_param — chain-walking 5-deep lookup for ::<mat>::Mobility::<model>::<carrier>::<key>. matparam_sub3 is 4-deep including link, so we need one more level. Walks the inherit chain (self → root) and returns the first hit.
---- 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.
---- 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).
---- INIT ----
Return all (Mat, Sol) keys currently in the accumulator.
---- inspection helpers ----
---- SET_SELF (own bulk contribution, idempotent across rebuild passes) ----
register_farahmand_mobility — emit the two standard mobility shims for a III-N material in one line. Per Phase 2 of the bottom-up refactor. Replaces: proc <Mat>::ElecMobility args { ::FarahmandLowFieldMobility {*}$args mat=<Mat> } proc <Mat>::HoleMobility args { return [matparam <Mat> HoleMu] } Usage: register_farahmand_mobility GaN register_farahmand_mobility AlN
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.
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
stress — elastic Newton solve. Subcommands: stress pull pull-mode elastic equation setup stress [calcstress] Newton solve + (default) materialise TSXX..TSZX stress !calcstress skip the tensor materialisation Dispatches the actual solve through `solve stress`, which calls RunStressSolve in src/device/stress.cc.
Declare common stress-deck variant materials with their canonical parents. Idempotent. Each variant's parent base is initialized first via its `::ElasticInit` (which auto-declares its own parent recursively, ending at BaseMat). Variants are no longer listed here — each variant declares itself via `elastic_variant <Variant> <Parent>` in its parent's ElasticEquations.tcl (e.g., STIox / ILDox / HiK in Oxide/ElasticEquations.tcl). The full `mater list`-style registry lives at `::Elastic::Variants`, populated at file-source time when StressPackage's pre-init loop calls each `<base>::ElasticInit`. Call this BEFORE `init inf=...` if the loaded structure references the variants — otherwise the structure-file load will register the variants without inheritance, and StressPackage's dispatch loop can't resolve them via `mater get.inherit`.
Convenience dispatch.
2D anisotropic stress equation. Uses the 5-entry ATensor( c00 c01 c10 c11 c33 ) form and the 2D-RHS compliance scaling (1 - s_iz/s_zz) on the in-plane user strains. Requires the full 15-element list (needs s02/s12/s22).
3D anisotropic stress equation. Takes the 12- or 15-element list returned by set_aniso_elastic / set_transverse_iso_elastic. The strain term uses `ATensor(c00..c33,c33,c33)` (Tshear form) — the alagator assembler expects the shear-block of the strain-coupling tensor to have identical diagonal entries c33, not the full c33/c44/c55 Voigt-rotated values. Matches the working pattern in the legacy updatedstressprocs.source / anisoprocs.source. An earlier "T for both" form (used by Stress3DAniso in src/FLOOXS.models) produced an `ElasticTerm::Assemble has a size mismatch` panic at solve time.
2D isotropic stress equation with (1+ν) user-strain scaling and 2D stress components only.
3D isotropic stress equation from Young's modulus + Poisson ratio.
3D transverse-iso stress equation. Uses the full ATensor (no c33-repeated Tshear form) for the strain term — matches the legacy Stress3DTransIso in the deleted FLOOXS.models block byte-for-byte.
Scan Tcl's auto_index for `::<Mat>::ElasticInit` entries (the auto-load triggers emitted by the elastic_base declarator). Pre-Phase 4 this scanned for `::<Mat>::ElasticEqns` shims; the per-material shims are gone now, replaced by the generic `::ElasticEqns mat=<Mat>` dispatch.
stress pull — pull-mode elasticity setup. Walks `mater list`, dispatches each material: (a) Material has a `::Models <Mat> Elasticity` entry → composer (`__compose_elasticity` in `TclLib/Models/StressCompose.tcl`) validates the chosen Anisotropic / Isotropic slice and pre-stamps the matparam keys (::<Mat>::Model, ::<Mat>::C11/12/44 OR ::<Mat>::YoungsModulus/PoissonRatio, optional ::<Mat>::ThermalAlpha) that the legacy `::ElasticEqns` dispatcher reads. (b) Material has no `::Models <Mat> Elasticity` entry → falls back to the legacy `namespace eval Mat { variable C11 ... }` declarations in `TclLib/Device/<Mat>/ElasticEquations.tcl`. After the per-material dispatch, this proc initializes the strain / stress / displacement field surface and walks `mater list` to emit per-region elasticity PDEs via `::ElasticEqns`. `StressPackage` is no longer called — its body is unreachable from `stress pull`. Decks that still call `StressPackage` directly continue to work until Phase G migrates them. See `doc/BOTTOMUP.md` §14.
Walk a material's inherit chain until we find a link registered as an elastic base (via `elastic_base`). Returns the namespace name, or "" if no link in the chain has elastic data. Touches `::Elastic::ParentOf` (populated when `elastic_base` runs at file-source time); calls `<X>::ElasticInit` for each candidate to force-source its ElasticEquations.tcl if not already loaded.
Surface diffusion-limited rate at a Mat/Side interface. Uses Side's D0 + Lspa and Mat's KinkSite.