Part 2 · Model execution and studies

Executing the trade studies on a SysML v2 plant model

Supports the main post.

1Introduction

We want to iterate on engineering designs quickly enough to learn from them. That means varying numerical parameters, comparing component and material choices, and changing how the system is assembled. After each change, we want to evaluate the consequences: what performance does this design deliver, what does it cost, and which engineering limits does it violate?

The earlier post on agentic modeling described why SysML v2 is useful for representing these alternatives. This post explains how we turn those models into executable calculations with sysml-codegen, run them with TEAx, and why we designed the pipeline this way.

1.1Exploring the design space: parameters, components, and architecture

Each kind of design change needs different support from the model and its executable program.

Figure 1 sets the three kinds side by side. Each card names a kind of change and describes it; the band above the cards says how we iterate on it.

Run the existing program with different inputs

Parameters

Numerical parameters let us explore choices such as dimensions and operating conditions while keeping the same components and equations. The generated program exposes these values as inputs, with initial settings in JSON files. A study can vary the inputs and evaluate the resulting designs without changing the program.

Edit the SysML model and generate a new program

Components and materials

Component and material choices are categorical: we select one alternative or another. These choices do not fit naturally into a numerical parameter sweep, because an alternative may bring different properties, equations, and engineering limits. In SysML, a component definition describes a kind of component and its calculations; a usage places a component of that kind in a particular design. We can create alternative definitions and select which one a design uses.

Architecture

Architectural choices change the assembly itself: how many components there are and how they connect. The plant model expresses these choices through component usages and their connections. Codegen uses that assembly to construct the calculation network, so changing the assembly changes which calculations run and where they get their inputs.

Figure 1Three kinds of design change and the two ways we iterate on them.

These choices lead to two ways of iterating. A numerical study runs the existing program with different inputs. Changing component definitions or plant architecture generally means editing the SysML model and generating a new program. Both let us evaluate the consequences of a design decision.

1.2Why build an execution pipeline?

Two reasons. First, when we started, we did not have an out-of-the-box SysML v2 execution tool ready for this workflow. Second, we needed machinery that agents could easily configure and run within a harness. That meant programmatic control over the model's inputs and repeated evaluations, along with the ability to incorporate custom calculations beyond what our SysML execution tools supported.

To support those studies, we built a code-generation pipeline that turns an assembled SysML plant model into an executable Python program. The program accepts design parameters, calculates performance and cost, and checks engineering limits. TEAx runs it repeatedly so a study can compare different design points.

Python also gives us access to more sophisticated computation and flexibility than we can express and execute through our supported SysML subset alone. Later, we will show how a custom calculation, such as a surrogate for a detailed simulation, can become part of the plant model.

1.3From component models to a study

Our demo models and explores stellarator designs. To show how the codegen pipeline works, we will focus on a study of the magnet system: how changing plant radius and coil ampere-turns affects cost and the design's ability to meet engineering limits.

We will follow the component equations and plant connections through code generation, then show how the resulting program evaluates and compares design points.

One model, two kinds of iteration
Stellarator component changes regenerate the program. Parameter studies reuse it.
Author the plant
  • SysML parts and connections
  • Magnet, blanket, plasma, cooling
  • Equations + engineering checks
Generate the program
  • Resolve calculation inputs
  • Translate equations to Python
  • Write the TEAx connections
Evaluate a candidate
  • Set radius and ampere-turns
  • Calculate outputs and cost
  • Record constraint results
Change the model

Example: replace the blanket’s held breeding value with a transport-response calculation.

Change the parameters

Example: sweep radius and coil ampere-turns using the same generated package.

Figure 2Model changes regenerate the program; parameter studies reuse the generated stellarator program.

The worked example follows our stellarator demo through seven steps:

  • 2.1 Model a component: separate the magnet's reusable equations from the values and connections chosen for the plant.
  • 2.2 Define acceptable designs: express engineering limits as constraints that each design point must pass.
  • 2.3 Construct the calculation network: determine where every calculation gets its inputs and which other calculations it depends on.
  • 2.4 Implement the mathematics: translate equations into Python and incorporate custom methods, including a simulation surrogate.
  • 2.5 Change the component model: give the blanket a more detailed calculation while keeping its place in the plant.
  • 2.6 Assemble the executable program: connect the Python calculations with TEAx and expose the inputs a study can vary.
  • 2.7 Run a study: evaluate many design points and compare their feasibility and cost.

All code examples come from the stellarator demo as read on 19 September 2026. Excerpts omit surrounding imports and documentation where indicated.

2Process: a worked example

2.1Modeling a component: separate its equations from the plant's choices

We begin by defining a component’s calculations and connecting their inputs and outputs to the plant model.

The stellarator's magnets produce the magnetic field that confines the plasma. For a proposed design, we want to calculate that field from the chosen coil ampere-turns and geometry. Other calculations then use the result to evaluate the plasma and check the magnet's engineering limits.

The magnet model uses a reusable field equation. The plant supplies the design values and connects the magnet to the plasma's radius. The figure below shows how those values reach the equation and how its result becomes available to the rest of the plant.

The equation, the plant inputs, and the calculated field
Actual SysML excerpts · imports, documentation, and other members omitted; empty braces held documentation
3Calculation definition · the mathematical relationship
calc def 'Coil Set Axis Field' {
    in attribute n_coils : Real;
    in attribute I_coil : Real;
    in attribute k_link : Real;
    in attribute R0 : Real;
    in attribute mu0 : Real default 1.25663706212e-6;
    in attribute two_pi : Real default 6.283185307179586;

    out attribute B_axis : Real = mu0 * k_link * n_coils * I_coil / (two_pi * R0);
}
1Plant usage · supplies the coil values
part stellaris : 'MFE Power Plant' {
    part :>> magnet {
        part :>> coil {
            :>> n_coils = 48.0 {}
            :>> I_coil = 15400000.0 {}
            :>> k_link = 0.7731331164622419 {}
        }
    }
}

Inherited coil binding from 'MFE Power Plant':

:>> R0 = plasma.R {}
2Calculation usage · selects those values
calc field_calc : 'Coil Set Axis Field' {
    in n_coils = coil.n_coils;
    in I_coil = coil.I_coil;
    in k_link = coil.k_link;
    in R0 = coil.R0;
}

Owned by 'Magnet System'. mu0 and two_pi retain their defaults.

4Component attribute · exposes the result inside 'Magnet System'
attribute B : Real = field_calc.B_axis;
Figure 3Sources: the calculation definition models/library/analyses/mfe_magnet_field.sysml, magnet component definition models/library/cost_structure/mfe_power_core.sysml, generic plant connections models/designs/generic_mfe/mfe_plant.sysml, and stellarator design values models/designs/stellarator_09/stellarator_plant.sysml. Documentation and unrelated members are omitted. The calculation usage and exposed attribute belong inside 'Magnet System'; the radius connection is inherited from the generic plant.

The walk below follows the numbered boxes in Figure 3: the plant's values (1), the calculation usage that selects them (2), the equation they feed (3), and the attribute that exposes its result (4).

Start with the plant's choices. At the reference point, it specifies 48 coils and 15.4 million ampere-turns per reference coil. The coil's radius attribute, coil.R0, is connected to the plasma's major radius, plasma.R. Changing the plant's plasma radius therefore also changes the radius used by the magnet.

The calculation definition declares the field equation and its inputs. Inside the magnet, the calculation usage, field_calc, connects the coil's attributes to those inputs. For example, it binds the equation's R0 input to coil.R0, completing the connection from the plant's plasma radius to the field equation. The equation's constants, mu0 (vacuum permeability) and two_pi (twice π), come from their declared defaults.

The equation returns the calculated field as B_axis. The magnet exposes that result through an attribute named B, which other components and calculations can read. Downstream calculations use it to determine peak conductor field and plasma beta, the ratio of plasma pressure to magnetic pressure. A new radius or coil ampere-turn value therefore affects both the field calculation and the calculations that depend on its result.

Reference pointThe field equation at the plant's values

This evaluates the one equation in Figure 3, B_axis = mu0 · k_link · n_coils · I_coil / (two_pi · R0), with n_coils = 48 and k_link = 0.7731 held at the plant's values and the constants at their defaults. Nothing downstream of it is calculated here.

At R0 = 12.7 m and I_coil = 15.4 MA-turn, the equation gives B_axis = 9.00 T. The plant's reference values give 9.0 T, the axis-averaged field of the reference design.

Scope

The physical scope of this equation matters when interpreting those results. Here I_coil denotes ampere-turns per reference coil; current in an individual conductor is checked separately. The equation estimates axis-averaged field using a fixed linkage factor from the reference coil set. It is a reference-scaled approximation, not a full three-dimensional magnetic-equilibrium calculation.

2.2Constraints test whether a design point meets engineering limits

Next, we add constraints that test whether a design meets the modeled engineering limits.

Later, we will show how a study sweeps across a wide range of input combinations, such as plant radius and coil ampere-turns. Each complete set of input values defines a design point. The calculations tell us what performance and cost each point produces, but some combinations will violate engineering limits. We need a way to identify those failures as the study runs.

We express engineering limits as constraints: expressions that evaluate to true or false for a design point. A constraint can compare a calculated quantity with a limit, or relate several quantities that must be consistent with one another. In SysML, an assert constraint applies the condition to the model so the generated program can check it during evaluation.

For example, the magnet's conductor is arranged into a winding pack, which must fit inside its casing. A larger pack may provide the needed current capacity, but it also needs enough physical space.

The magnet's fit calculation compares the pack dimensions with the available space, accounting for insulation and assembly allowances. It calculates clearance in two directions and exposes the smaller margin as fit_minimum_margin.

Figure 4 shows what that calculation compares, in a cross-section of one coil. Read it from the outside in: the casing wall, the cavity it leaves, then the required envelope, which is the pack plus its insulation and assembly clearance on every face. The shaded band between the envelope and the cavity is the margin, one value in the radial direction and one in the transverse direction; the check reads the smaller of the two. The proportions are schematic, and the layers are drawn thicker than they are.

What the fit calculation comparesCross-section of a magnet coil: the casing wall encloses a cavity; inside it, centred, the winding pack is wrapped in ground insulation and an assembly clearance on every face. The required envelope is the pack plus those allowances. The radial margin is the cavity's radial width minus the required radial width; the transverse margin is the same in the transverse direction. The check reads the smaller of the two. winding pack nominal + internal build margin, split over both sides cavity_x = radial_allocation − 2 × wall_thickness required_x cavity_y = interior_y required_y casing wall wall_thickness, each radial side assembly clearance assembly_clearance, each face ground insulation ground_insulation, each face What the check reads margin_x = cavity_x − required_x margin_y = cavity_y − required_y minimum_margin = min(margin_x, margin_y) x is radial, toward the plasma face; y is transverse. Both are normal to the conductor.
Figure 4What the winding-pack fit calculation compares: the casing cavity against the pack's required envelope, in the radial and transverse directions. Names are the calculation's own; equations from the documentation of models/library/analyses/mfe_winding_pack_fit.sysml.
In the modelWhat the fit calculation reads

Inside the magnet, the fit calculation takes the pack's size and build-up from the winding pack, the radial space from the coil, and the cavity from the casing:

models/library/cost_structure/mfe_power_core.sysmlSysML
calc wp_fit : 'Winding Pack Casing Fit' {
    in wp_side = winding_pack.wp_side;
    in aspect_ratio = winding_pack.fit_aspect_ratio;
    in internal_fraction_x = winding_pack.internal_build_x;
    in internal_fraction_y = winding_pack.internal_build_y;
    in ground_insulation = winding_pack.ground_insulation;
    in radial_allocation = coil.coil_t;
    in interior_y = casing.interior_y;
    in wall_thickness = casing.wall_thickness;
    in assembly_clearance = casing.assembly_clearance;
}

attribute fit_minimum_margin : Real = wp_fit.minimum_margin;

It compares a centered rectangular winding envelope with the casing cavity left after insulation and assembly allowances. The calculation is written by hand in Python; section 2.4 covers calculations like it.

The reusable constraint definition models/library/analyses/mfe_winding_pack_fit.sysml states the condition: the minimum clearance must be nonnegative.

models/library/analyses/mfe_winding_pack_fit.sysmlSysML
constraint def 'Winding Pack Fits Casing' {
    in attribute minimum_margin_in : Real;
    minimum_margin_in >= 0.0
}

The stellarator plant applies that condition to its magnet's calculated clearance:

models/designs/stellarator_09/stellarator_plant.sysmlSysML
assert constraint wp_fit_ok : 'Winding Pack Fits Casing' {
    in minimum_margin_in = magnet.fit_minimum_margin;
}

A negative clearance means the winding pack does not fit. The program still reports the design's calculated performance and cost, alongside the failed check. That lets a study show what a proposed change improves and which engineering limits it violates.

Scope

This fit check covers a local rectangular cross-section of the pack and casing cavity. Passing it does not establish that the entire nonplanar coil can be manufactured or assembled.

A design point passes the modeled feasibility checks only when all applicable assertions have been evaluated and satisfied. Results identify which assertions were assessed; an unassessed check cannot count as a pass. Even a point that passes every check still needs evidence for engineering limits the model does not yet represent.

2.3Reconstructing the calculation network

Codegen now identifies the calculations used by the assembled plant and determines where each one gets its inputs.

Those connections determine what must be calculated first. The program cannot check winding-pack clearance until it knows the pack dimensions, and in the version shown here it could not calculate those dimensions until it knew how much conductor the current needed. TEAx will use these dependencies to order the calculations when it runs the program.

SysML organizes the model around physical components. Codegen constructs a second view organized around calculations: each calculation is a node, and a connection from one calculation's output to another's input is an edge. This is the computational graph. It tells the execution system which results must be available before a calculation can run. The following figure shows the magnet branch of the generated stellarator graph.

G How magnet calculations depend on one another radial_build Radial build Coil position coil_length Coil length radial_build->coil_length peak_field_calc Peak conductor field radial_build->peak_field_calc field_calc Axis field field_calc->peak_field_calc wp_volume Winding-pack volume coil_length->wp_volume winding_procurement Winding quantities and cost coil_length->winding_procurement current_sizing Current-driven pack sizing peak_field_calc->current_sizing conductor_current Conductor current margin peak_field_calc->conductor_current peak_field_ok CHECK Field limit peak_field_calc->peak_field_ok wp_sizing Winding-pack side length current_sizing->wp_sizing wp_fit Pack / casing fit margins wp_sizing->wp_fit wp_sizing->wp_volume wp_fit_ok CHECK Pack fits casing wp_fit->wp_fit_ok material_inventory Material inventory wp_volume->material_inventory material_inventory->winding_procurement winding_procurement->conductor_current Tape + conductor lengths reference_conductor_current_ok CHECK Current margin conductor_current->reference_conductor_current_ok

Each arrow is an actual output-to-input binding. Secondary inputs and other plant branches are omitted. Amber boxes assess values; they do not resize the design.

ConnectionsWhat a calculation depends on, and what depends on it

Fourteen calculations and checks of the magnet branch, joined by the eighteen recorded output-to-input bindings; the panel below the figure lists all eighteen.

Figure 5Each arrow connects a calculation's output to another calculation's input. Multiple values exchanged by the same pair share an arrow. Secondary inputs and other plant branches are omitted. Exact nodes, connections, and package identities: archive/write-up/sysml-codegen-assets/graph-evidence.md.
In the recordThe 18 connections behind the graph

Each row is one output-to-input binding in the generated stellarator program, as captured on 19 September 2026. A calculation with a single result is named without an output. All eighteen match, name for name, the pipelines frozen with the 15 September and 17 September studies of section 2.7; that comparison covers names, types and bindings, not implementations or results.

FromTo
radial_build.r_coil_centrecoil_length.a_coil
field_calcpeak_field_calc.B_axis_in
radial_build.r_coil_centrepeak_field_calc.a_coil_in
peak_field_calccurrent_sizing.B_peak
current_sizing.selected_effective_densitywp_sizing.j_wp
wp_sizingwp_fit.wp_side
coil_lengthwp_volume.c_coil
wp_sizingwp_volume.wp_side
wp_volume.vol_winding_packmaterial_inventory.volume_in
material_inventory.material_costwinding_procurement.material_cost_in
material_inventory.tape_volumewinding_procurement.tape_volume_in
coil_lengthwinding_procurement.c_coil
winding_procurement.conductor_lengthconductor_current.conductor_length
winding_procurement.tape_lengthconductor_current.tape_length
peak_field_calcconductor_current.B_peak
peak_field_calcpeak_field_ok.B_peak
conductor_current.margin_fractionreference_conductor_current_ok.margin_fraction_in
wp_fit.minimum_marginwp_fit_ok.minimum_margin_in

Read the graph from the top. The calculated field and magnet geometry determine the peak field at the conductor. That field affects how much current the conductor can carry, so it feeds the calculation that sizes the conductor supply. The sizing result then feeds the calculation of winding-pack dimensions.

The pack dimensions feed two branches: one checks whether the pack fits, while the other calculates material quantities and their procurement cost. A separate check determines whether the resulting conductor supply can carry the required current. Following the arrows shows how a change in field can affect both the physical fit and the cost of the magnet.

This graph is the model as it stood on 19 September. The next day we removed the two sizing calculations, because they chose the winding's size from the current instead of evaluating a size the designer supplies (section 2.7.1). The pack side is now a supplied input: the fit and volume calculations read it directly, the cost calculations follow from the volume, and the current check reports whether that winding carries its current. Codegen resolves and orders those connections the same way.

This execution order depends on the model author declaring each calculation's inputs and outputs. If two calculations each need the other's result before they can run, neither can start. The pipeline therefore requires a network without circular dependencies (a directed acyclic graph, or DAG). It does not rearrange equations or build a solver automatically; a coupled calculation needs a numerical method supplied by the author. The direction of the connections also fixes which values a study can set: a value one calculation produces cannot also be supplied as a design choice.

Codegen constructs this network in three steps.

  1. SysIDE reads the SysML declarations and resolves references between them.

    It gives codegen a structured representation of the components, equations, and connections in the model.

  2. Codegen walks the plant's component hierarchy to find each use of a component definition.

    These records let components have their own values even when they share a definition.

  3. Codegen now follows the model's connections to find the value supplying each calculation input.

    It follows connections through attributes until it reaches either an external input or a calculation output.

Figure 6The three steps codegen takes to construct the calculation network. Each step's label opens its detail below.

2.3.1Parse declarations and references

SysIDE reads the SysML declarations and resolves references between them. When a calculation names coil.I_coil, SysIDE identifies the declared attribute that name refers to. It gives codegen a structured representation of the components, equations, and connections in the model.

Identifying a declaration is only the first step. A reusable component definition can be used at several places in a plant, with different values at each place. Codegen must determine which use of the component a calculation belongs to.

2.3.2Expand the assembled design

Codegen walks the plant's component hierarchy to find each use of a component definition. At each location, it applies the definitions and overrides selected by the plant and creates records for that component's values, calculations, and checks. For the stellarator's magnet, this includes the field calculation from section 2.1 and the fit check from section 2.2.

Each component at a particular location in the assembly is an occurrence. The field equation is declared in the reusable magnet definition; its occurrence in this plant belongs to stellaris.magnet. If the same definition is used elsewhere, codegen creates separate records for that occurrence. Components declared as arrays are also expanded into individual occurrences.

These records let components have their own values even when they share a definition. The next step connects calculations to those values, including values shared across components.

2.3.3Resolve each input to its supplier

Codegen now follows the model's connections to find the value supplying each calculation input. The radius connection from section 2.1 shows how this works: the field calculation reads coil.R0, and the plant connects that attribute to plasma.R. Following the chain reaches the plant's plasma-radius parameter, so the generated field calculation reads that input directly.

The pack-sizing calculation in the version shown here illustrates the other case. Its effective current density, the current per unit winding-pack area, came from the current-sizing calculation. Following that connection reaches a calculated output, so codegen adds an edge from current sizing to pack sizing. The program must calculate the density before it can use it to calculate pack dimensions.

In both cases, codegen uses the declaration identified by SysIDE together with its location in the assembled plant to find the supplying value. It follows connections through attributes until it reaches either an external input or a calculation output. Several calculations that reach the same supplier remain connected to that same value.

A missing or ambiguous supplier stops generation with a diagnostic. A broken connection cannot silently become an adjustable study parameter. Once the connections are resolved, codegen has the calculation network it needs to generate the executable program.

2.4Turning modeled mathematics into executable Python

The graph tells us which calculations are needed and how they depend on one another. Each calculation also needs executable code that turns its input numbers into output numbers. For equations written in the supported SysML expression language, codegen generates that code directly, so the author does not have to maintain a second copy of the equation in Python.

Consider the magnetic-field equation from section 2.1. SysIDE represents its arithmetic as nested operations: multiply the numerator's terms, multiply the denominator's terms, then divide. Codegen visits those operations and writes the equivalent Python expression. The equation's I_coil input, for example, becomes inputs.I_coil in Python. The generated function exploration/stellarator_e2e/generated/handwritten/mfe_magnet_field/coil_set_axis_field_impl.py returns:

exploration/stellarator_e2e/generated/handwritten/mfe_magnet_field/coil_set_axis_field_impl.pyPython
return ((((inputs.mu0 * inputs.k_link) * inputs.n_coils) * inputs.I_coil)
        / (inputs.two_pi * inputs.R0))

Only the line break has changed for readability. A generated wrapper checks the inputs and packages the result so TEAx can call the calculation.

In the packageThe generated wrapper around it

Beside the implementation file, codegen writes a module wrapper for TEAx. It declares a typed input record (a pydantic model with one field per declared input: two_pi, I_coil, R0, n_coils, k_link, mu0) and a run method that validates the inputs, imports the implementation, runs it and returns the result in TEAx's result type. The method, comments included, as generated:

exploration/stellarator_e2e/generated/modules/mfe_magnet_field/coil_set_axis_field.pyPython
def run(
    self, two_pi: float, I_coil: float, R0: float, n_coils: float, k_link: float, mu0: float    ) -> ModuleResult[Float]:
    # Validate inputs
    validated_inputs = self.validate_and_fill_default(two_pi, I_coil, R0, n_coils, k_link, mu0)

    # Import handwritten implementation
    from stellarator_tea.handwritten.mfe_magnet_field.coil_set_axis_field_impl import (
        run_coil_set_axis_field,
    )

    # Execute implementation - returns single value
    B_axis = run_coil_set_axis_field(validated_inputs)

    # Single output - return Float directly (RootModel[float])
    # TEAx assigns entire return value to the one channel declared in YAML
    return ModuleResult(data=Float(B_axis))

The docstrings are omitted. The wrapper is the same shape whether the implementation was translated from the SysML expression, as here, or written by hand, as in section 2.4.1.

The compiler supports a subset of SysML mathematics. The generated code does not automatically convert units, so equations and supplied values must use consistent units.

2.4.1Incorporating calculations beyond the expression translator

Some engineering calculations need numerical algorithms, external libraries, or a fast approximation to an expensive simulation. For these methods, the model declares the calculation's inputs, outputs, and plant connections. Codegen generates the Python interface, and the author supplies the computational method. TEAx can then run that method alongside the automatically translated equations. An untranslated calculation cannot run until its implementation is supplied.

The blanket surrounding the plasma uses fusion neutrons to breed tritium fuel. We want to explore how its thickness affects breeding, but running a detailed neutron-transport simulation at every design point would be expensive.

Instead, the model uses a response table from prior neutron-transport calculations models/designs/stellarator_09/breeding_response.json. A handwritten Python function exploration/stellarator_e2e/generated/handwritten/mfe_tritium_breeding/blanket_tritium_breeding_impl.py estimates the breeding response between the stored results by interpolation. That function is a surrogate: a cheaper approximation to the detailed simulation, which the plant can call at each design point.

Figure 7 shows the five stored results and the response the function returns between them. Each dot is one transport calculation; the line between two dots is the straight interpolation the function uses. The shaded band spans the stored results.

0.5 0.6 0.7 0.8 0.9 1.0 1.1 Blanket thickness (m) 1.05 1.10 1.15 1.20 1.25 Tritium breeding ratio (Li-6 + Li-7) 1.091 1.252 defined: five stored results, 0.60 to 1.00 m undefined undefined Stored transport results and the interpolated response
One thicknessThe surrogate at one blanket thickness

At 0.800 m, the stored result is a tritium breeding ratio of 1.198 (Li-6 1.195 plus Li-7 0.003). Between two stored thicknesses the function interpolates linearly; outside 0.60 to 1.00 m it returns the response as undefined.

Figure 7The blanket's breeding response table and the surrogate's interpolation. Five stored neutron-transport results at 0.60, 0.70, 0.80, 0.90 and 1.00 m, with the remaining geometry and scenario fixed; the tritium breeding ratio shown is the Li-6 and Li-7 contributions summed. Data: models/designs/stellarator_09/breeding_response.json.

The table contains results at five blanket thicknesses spanning 0.60–1.00 m, with the remaining geometry and scenario assumptions fixed. The function checks that the inputs stay within those conditions and marks the response undefined outside them.

In the codeThe response table and the interpolation

The handwritten function embeds the table from the design-owned response asset. Its five nodes, with the standard error of each transport result:

Thickness (m)TBR from Li-6TBR from Li-7Standard error
0.601.088120.003330.00162
0.701.150670.003350.00156
0.801.194730.003350.00096
0.901.227600.003360.00183
1.001.249090.003360.00165

After checking that every input is finite, that the geometry inputs equal the table's fixed geometry, and that the thickness lies within the table, the function interpolates:

exploration/stellarator_e2e/generated/handwritten/mfe_tritium_breeding/blanket_tritium_breeding_impl.pyPython
index = min(bisect.bisect_right(thicknesses, thickness) - 1, len(nodes) - 2)
left, right = nodes[index:index+2]
fraction = (thickness - left['thickness_m']) / (right['thickness_m'] - left['thickness_m'])
li6 = left['tbr_li6'] * (1-fraction) + right['tbr_li6'] * fraction
li7 = left['tbr_li7'] * (1-fraction) + right['tbr_li7'] * fraction
mean = li6 + li7
variance = ((1-fraction)*left['std_error'])**2 + (fraction*right['std_error'])**2

It returns the mean with a defined flag of 1, and also a numerical lower estimate, the mean less twice the interpolated standard error and a 0.01 interpolation allowance. That lower estimate is a numerical margin, not a physical confidence bound. When a check fails, the function returns seven zeros with the defined flag at 0; those zeros are not a prediction of zero breeding. The table's provenance (OpenMC 0.15.2, the fixed geometry and material scenario) is recorded in the response asset. The file declares AUTO_IMPLEMENTED = False.

Both translated equations and custom methods expose declared inputs and outputs, so codegen can connect them into the same plant calculation network. The implementation note archive/write-up/sysml-codegen-assets/model-evidence.md, "Implementation preservation", covers how Python bodies are retained when regenerating a package.

In the noteHow Python bodies survive regeneration

Both translated and custom Python implementations live under handwritten/ in the generated package. When a package is regenerated, a preservation option can keep an existing body whose interface is unchanged, even if the SysML equation changed; a fresh generation updates the translated equations, and a retained implementation has to be checked against the revised model.

For a calculation whose expression cannot be translated, codegen writes the function interface with a placeholder body that raises NotImplementedError until the author supplies the method. The declared inputs and outputs already place that calculation in the plant's network, and broken plant wiring still stops generation.

2.5Selecting a different component model

Changing numerical inputs lets us explore a component model’s existing behavior. To explore a different component or add more detailed behavior, we need to select a different definition for that component in the plant.

The blanket provides an example of adding detail. Its base model supplies a fixed breeding estimate, so varying blanket thickness does not change the breeding result. We want to replace that assumption with the thickness-dependent calculation introduced in section 2.4.

The stellarator design inherits a common plant assembly that already includes a blanket and its connections. The more detailed definition extends the base blanket, and the stellarator selects it for the existing blanket usage. Other parts of the plant can continue reading the breeding result from that same component.

The three declarations below express those choices. They come from separate source locations; the bodies are omitted:

Three declarations, three files, and what each points at
The code block laid out by relationship, each declaration with the design choice it expresses. Each arrow is one keyword in the code: read it from the box it starts in.
Base definition · models/designs/generic_mfe/mfe_subsystems.sysml · not in the code block
part def 'Blanket' :> 'CAS22 Power Core' {
    attribute tbr : Real default 1.0;
    // ...
}

The kind both other declarations refer to. Its breeding ratio is a held value.

:>extends
Specialized definition · models/designs/generic_mfe/mfe_subsystems.sysml
// Specialized component definition
part def 'Transport Calculated Blanket' :> 'Blanket' {
    // ...
}

The specialized definition extends that base with :> and adds the breeding calculation inside its omitted body.

of kind: 'Blanket'
selects: 'Transport Calculated Blanket'
Generic plant usage · models/designs/generic_mfe/mfe_plant.sysml
// Generic plant: the inherited component usage
part blanket : 'Blanket' {
    // ...
}

The common plant assembly declares a blanket component using the base definition.

:>>redefines
Stellarator design · models/designs/stellarator_09/stellarator_plant.sysml
// Stellarator design: select the specialization
part :>> blanket : 'Transport Calculated Blanket' {
    // ...
}

The stellarator design redefines the inherited blanket usage with :>>, selecting the more detailed definition for that component.

In the modelWhat the specialized body adds

The base 'Blanket' holds its breeding ratio as a value, attribute tbr : Real default 1.0;. The specialization owns the breeding calculation and redefines that same attribute to read the calculated mean, so every other part of the plant that reads tbr is unchanged. Members omitted where marked:

models/designs/generic_mfe/mfe_subsystems.sysmlSysML
part def 'Transport Calculated Blanket' :> 'Blanket' {
    attribute breeding_R : Real;
    attribute breeding_a : Real;
    // ... five more geometry attributes the plant binds
    calc breeding : 'Blanket Tritium Breeding' {
        in blanket_t_in = blanket_t;
        in R_in = breeding_R;
        in a_in = breeding_a;
        // ... the remaining geometry inputs
    }
    :>> tbr = breeding.tbr_mean;
    attribute tbr_lower : Real = breeding.tbr_lower;
    attribute breeding_defined : Real = breeding.defined_flag;
    // ...
}

The stellarator's redefinition then binds the geometry the calculation needs from its own parts, for example :>> breeding_R = stellaris.plasma.R; and :>> breeding_a = stellaris.plasma.a;.

After this model change, we regenerate the program. Codegen includes the selected blanket's calculation and connects it to the plant, so the breeding result now comes from the surrogate. A study can vary blanket thickness and evaluate its effect on breeding alongside the other plant calculations.

2.6Putting together the Python computational model

We now have the calculation network and its Python functions, including any custom implementations. To run the plant, we need instructions for passing values between those functions and a way to supply the external inputs. The generated package captures both: a TEAx specification describes the connections, and input files hold the externally supplied parameters.

2.6.1Wiring the functions into an executable calculation network

A Python function for winding-pack size knows how to calculate a size from current density and ampere-turns. It does not decide which plant values to use. Codegen writes those choices into a YAML specification using the connections resolved in section 2.3. TEAx reads that specification to assemble and run the program.

Here is the complete pack-sizing entry from the stellarator pipeline:

exploration/stellarator_e2e/studies/20260917-pre-reveal-feasible-neighborhood/preparation/package-pipelines/pipeline.yamlYAML
stellarator_09__stellaris__magnet__wp_sizing:
  module_type: mfe_magnet_field.Winding_Pack_SizingModule
  inputs:
    j_wp: float stellarator_09__stellaris__magnet__current_sizing__selected_effective_density
    I_coil: float stellarator_plant_params.stellarator_09__stellaris__magnet__coil__I_coil
  outputs:
    root: RootModel[float] stellarator_09__stellaris__magnet__wp_sizing__wp_side

The module_type selects the winding-pack sizing calculation. Its j_wp input receives the density calculated by current sizing, while I_coil receives the supplied coil ampere-turns. The output entry names the calculated pack side so other calculations can read it. The long names identify each value's location in the plant. Generated pipeline: exploration/stellarator_e2e/studies/20260917-pre-reveal-feasible-neighborhood/preparation/package-pipelines/pipeline.yaml.

Figure 8 draws the same entry as connections. Read it left to right: the two inputs and where each comes from, the module in the middle, and the two calculations that read its output, taken from the bindings behind Figure 5.

The pack-sizing entry as connections
One calculated input, one supplied input, one output read twice
Calculation output
Current-driven pack sizing
stellarator_09__stellaris__magnet__current_sizing
selected_effective_density
Input file
stellarator_plant_params.json
stellarator_09__stellaris__magnet__coil__I_coil
15400000.0
Module
Winding-pack sizing
stellarator_09__stellaris__magnet__wp_sizing

in j_wp effective current density
in I_coil coil ampere-turns

module_type mfe_magnet_field.Winding_Pack_SizingModule, whose implementation is the handwritten square-root sizing function

out wp_side winding-pack side length

Reads wp_side
Pack / casing fit margins
stellarator_09__stellaris__magnet__wp_fit
wp_side
Reads wp_side
Winding-pack volume
stellarator_09__stellaris__magnet__wp_volume
wp_side
Figure 8The pack-sizing YAML entry drawn as connections: the effective current density arrives from the current-sizing calculation, the coil ampere-turns from the plant input file, and the calculated pack side is read by the fit and volume calculations. Sources: the entry above and the bindings in archive/write-up/sysml-codegen-assets/graph-evidence.md.
In the packageThe pipeline around this entry

The pipeline frozen with the 17 September study holds 113 entries: an entry point that loads the input files, 90 calculations, 20 constraint checks, one module that gathers the check results into a report, and an exit point. Across the calculations and checks, 423 inputs are bound to keys in the input files and 216 to outputs of other calculations. The field calculation's entry shows both kinds side by side; its constants come from a library parameter file and its four plant values from the plant file:

exploration/stellarator_e2e/studies/20260917-pre-reveal-feasible-neighborhood/preparation/package-pipelines/pipeline.yamlYAML
stellarator_09__stellaris__magnet__field_calc:
  module_type: mfe_magnet_field.Coil_Set_Axis_FieldModule
  inputs:
    two_pi: float mfe_magnet_field_params.stellarator_09__stellaris__magnet__field_calc__two_pi
    I_coil: float stellarator_plant_params.stellarator_09__stellaris__magnet__coil__I_coil
    R0: float stellarator_plant_params.stellarator_09__stellaris__plasma__R
    n_coils: float stellarator_plant_params.stellarator_09__stellaris__magnet__coil__n_coils
    k_link: float stellarator_plant_params.stellarator_09__stellaris__magnet__coil__k_link
    mu0: float mfe_magnet_field_params.stellarator_09__stellaris__magnet__field_calc__mu0
  outputs:
    root: RootModel[float] stellarator_09__stellaris__magnet__field_calc__B_axis

The package has grown since: the current generated pipeline holds 269 entries. After the 20 September model changes, the coil ampere-turns are calculated from the supplied turns and current per turn, so this field entry now reads them from that calculation. The pack-sizing entry above no longer exists, because the pack side is now a supplied input. The excerpts on this page are the 17 September package, the one the studies in section 2.7 ran.

TEAx uses these connections to run each calculation after the results it needs are available. It gathers the inputs, calls the Python function, and makes the outputs available to the next calculations. In the 17 September package, it computed field before current-based sizing, sizing before pack dimensions, and dimensions before the fit check.

2.6.2Exposing the free input parameters

The connected calculations still need starting values. In our example, the program calculates magnetic field, but the 17 September study supplied radius and coil ampere-turns; the current model calculates the ampere-turns from the supplied turns and current per turn. These externally supplied values form the program's input interface. Changing them lets us evaluate a new design point without regenerating the program.

Codegen identifies these externally supplied values while resolving the graph and exposes them as public inputs. The model's authored values provide their initial settings. Values supplied by another calculation remain connected to that calculation's output.

Here is an exact subset of the stellarator's generated plant-input JSON:

exploration/stellarator_e2e/studies/20260917-pre-reveal-feasible-neighborhood/preparation/package-inputs/stellarator_plant_params.jsonJSON
{
  "stellarator_09__stellaris__plasma__R": 12.7,
  "stellarator_09__stellaris__magnet__coil__I_coil": 15400000.0,
  "stellarator_09__stellaris__magnet__coil__n_coils": 48.0,
  "stellarator_09__stellaris__magnet__coil__k_link": 0.7731331164622419
}

These settings supply the plasma radius, coil ampere-turns, coil count, and linkage factor. Changing the radius changes the value received by every calculation connected to that plant attribute. The magnetic field remains a calculated result. Full generated input file: exploration/stellarator_e2e/studies/20260917-pre-reveal-feasible-neighborhood/preparation/package-inputs/stellarator_plant_params.json.

In the packageThe input files

The 17 September package has ten input files with 313 keys between them. Nine hold library defaults grouped by the model source that declares them (for example mfe_magnet_field_params.json, two keys: mu0 and two_pi); the plant file holds the 246 values the stellarator design supplies. Every key is flat and carries the component path, as the four above do.

In this package, eight calculations read the plasma radius, plasma__R, directly: the plasma geometry, radial build, plasma sustainment and divertor heat calculations, and in the magnet the axis field, peak field, stored energy and magnet cost. Seven read the coil ampere-turns, coil__I_coil: the axis field, stored energy, current sizing, pack sizing, winding-pack cost, winding procurement and pack stress calculations. A study that changes either value changes what all of them receive.

The long JSON keys identify each input's location in the plant. File-based runs load these settings from JSON; studies can supply the values directly in memory. The input-generation note archive/write-up/sysml-codegen-assets/model-evidence.md, "Input-generation details", covers file grouping, defaults, and inputs that need values before evaluation.

In the noteInput generation

When a calculation reads an externally supplied attribute, such as the plasma radius, codegen exposes that attribute as a public input, and every calculation that reads it shares the one input. A value supplied by a calculation stays connected to that calculation's output.

Authored values provide the initial settings. A literal bound directly to a calculation input is exposed with that literal as its initial value. An input left unbound becomes a public input with its modeled default, or a null placeholder that must be filled before evaluation. A missing or ambiguous reference stops generation; it does not become a free parameter.

Inputs are grouped into files, normally by their declaring model source. Keys within a file are flat and carry component paths rather than reproducing the nested component tree. Schemas describe types and defaults. File-based runs load JSON; studies can supply typed values in memory.

A study chooses which inputs to vary and which to hold fixed. In the radius–current study, radius and ampere-turns vary while coil count and linkage factor remain fixed.

2.7Running a study: compare feasibility and cost across design points

We can now use the generated program to ask an engineering question: which combinations of geometry and operating parameters meet the modeled limits, and what do they cost?

Figure 9 follows one study from left to right: the inputs it chooses, the program it loads once, the design points it evaluates, and the record it keeps. Below them are the study's two uses on this page, each a section of its own.

A study evaluates a set of design points against the same generated plant program.
  1. Chosen inputs

    Varied or held fixed

    It chooses which inputs to vary, which assumptions to hold fixed, and which results to compare. In the radius–current study, we vary plant radius and coil ampere-turns.

  2. The generated program

    Loaded once

    TEAx loads the generated program once, then evaluates each input combination independently.

  3. Each design point

    Evaluated independently

    For each combination, the program calculates electricity cost and reports which engineering checks pass or fail.

  4. The record

    Traced to the design that produced it

    The study records the inputs, calculated outputs, constraint results, and model version so each result can be traced to the design that produced it.

Two uses on this page

Compare a few proposed design changes

Three cases from the 15 September joint magnet-sizing study.

Map cost and feasibility across many input combinations

256 design points from the 17 September neighborhood study.

Figure 9How a study runs against the generated program, and the two uses of a study that the next two sections show.

The current study runner evaluates grids and prepared lists of candidates. An external optimizer can call the same evaluator; the study-runner note archive/write-up/sysml-codegen-assets/study-evidence.md, "Study runner capabilities", distinguishes that option from the built-in study strategies.

In the recordThe study record and the study runner

The 17 September study is a directory under exploration/stellarator_e2e/studies/20260917-pre-reveal-feasible-neighborhood/. Its parts, in the order a reader would open them:

  • record.md, the question, the axes, the verification scope and the limitations; report.md, the counts, held assumptions and cost limits; synthesis.md, the reading.
  • snapshot.json, the model version: the package path, its repository commit d53d6ec5… and the executable fingerprint f52729e6…, together with the input files' hashes.
  • preparation/, the frozen package (package-pipelines/pipeline.yaml, package-inputs/, schemas and contracts), resolved-defaults.json for every held value, and the proposals that were evaluated.
  • results/native-cases.json, each case's inputs, output channels and the verdict of every constraint; results/map-data.csv and results/analysis.json, the plotted coordinates and signed margins.

The study runner evaluates grids and prepared candidate lists. An external optimizer can call the same prepared evaluator, but adaptive optimization inside the runner is not implemented. The results on this page are retained candidate evaluations, not an adaptive search.

Snapshot

The following results illustrate two uses of a study: comparing a few proposed design changes, and mapping cost and feasibility across many input combinations. They come from two dated model snapshots. Their electricity costs reflect the assumptions and incomplete cost scope at that time; later breeding, cooling, and facility work changed the checks and cost estimates.

2.7.1See how a local change affects the rest of the design

With the tape performance we assume, the published Stellaris winding cannot carry its current: its tape would run at about 1.7 times its estimated critical current, where we allow 0.8. The winding also does not fit the radial space our model allocates for it. The 15 September joint magnet-sizing study exploration/stellarator_e2e/studies/20260915-joint-magnet-sizing/report.md evaluated two changes intended to fix this: enough tape to carry the current, then more space for the larger winding.

In that study, the model chose the amount of tape from the current requirement. We removed that option on 20 September, because a calculation that sizes equipment takes the choice away from the designer (Part 4b, section 2). The model now evaluates the winding a designer supplies, both its size and the space allocated for it, and reports any shortfall instead of resizing it. The three cases below are the September study's results: the original design, a design with enough tape to carry the current, and a design with more space for that tape.

Read Figure 10 left to right. Each card is one evaluated case: its electricity cost, the conductor it needs, and four of its check results. Between the cards is the one change made, with what it fixed and what it cost or broke. The small drawing on each card uses the vocabulary of Figure 4: the clear cavity with the required envelope inside it, or spilling out of it.

A design change can fix one limit and expose another
Three matched cases · 15 September magnet-sizing study · same 12.7 m major radius and 15.4 MA-turn
Original inventory
Conductor supply as entered; casing allocation 0.30 m radial, 0.40 m transverse
Required envelope against clear cavity, referenceClear cavity 0.250 by 0.400 m; required envelope 0.370 by 0.379 m; radial margin -0.120 m, transverse margin +0.021 m; the pack does not fit. required clear cavity does not fit
$144.75/MWh, conditional

Tape 36.6 million m · priced magnet subtotal $1.71 billion · peak field 24.90 T

  • Conductor currentFAILreference conductor cannot carry the required current
  • Pack / casing fitFAILradial margin −0.120 m, transverse +0.021 m
  • Peak field limitPASS24.90 T against 24.9 T
  • Divertor heat loadFAIL
Change 1
Size the conductor supply for the required current, with a 1% reserve
  • Fixes the current check.
  • Tape ×2.1; magnet subtotal +$0.84 billion; cost +$18.45/MWh.
  • The required envelope grows from 0.370 × 0.379 to 0.535 × 0.548 m, so it fits even less.
Size for required current
1% physical inventory reserve; original casing allocation
Required envelope against clear cavity, reference-sizedClear cavity 0.250 by 0.400 m; required envelope 0.535 by 0.548 m; radial margin -0.285 m, transverse margin -0.148 m; the pack does not fit. required clear cavity does not fit
$163.19/MWh, conditional

Tape 77.9 million m · priced magnet subtotal $2.55 billion · peak field 24.90 T

  • Conductor currentPASSfixedsized to carry it
  • Pack / casing fitFAILworseradial margin −0.285 m, transverse −0.148 m
  • Peak field limitPASS24.90 T against 24.9 T
  • Divertor heat loadFAIL
Change 2
Enlarge the space allocated to the magnet: 0.60 m radial, 0.60 m transverse
  • Fixes the fit: margins +0.012 and +0.049 m.
  • The changed radial geometry raises peak field 24.90 → 25.30 T, above the 24.9 T limit.
  • Tape +6%; cost +$3.55/MWh.
Add casing space
Keep current-based sizing; casing allocation 0.60 m radial, 0.60 m transverse
Required envelope against clear cavity, reference-accommodatedClear cavity 0.550 by 0.600 m; required envelope 0.538 by 0.551 m; radial margin +0.012 m, transverse margin +0.049 m; the pack fits. required clear cavity fits
$166.74/MWh, conditional

Tape 82.4 million m · priced magnet subtotal $2.70 billion · peak field 25.30 T

  • Conductor currentPASS
  • Pack / casing fitPASSfixedradial margin +0.012 m, transverse +0.049 m
  • Peak field limitFAILnew25.30 T against 24.9 T
  • Divertor heat loadFAIL
Figure 10Three cases evaluated with the same generated program. The second lets the model size the conductor supply for the required current, with a 1% reserve, an option since removed. The third also enlarges the space allocated to the magnet and its winding pack. None passes every check: all three exceed the modeled divertor heat-load limit. Extracted values and original case identities: archive/write-up/sysml-codegen-assets/magnet-sizing-comparison.csv.
In the recordThe three recorded cases

Three matched cases from the 15 September study's own executable (package commit a8589d6b…), candidates c0000, c0005 and c0007, report aliases reference, reference-sized and reference-accommodated. All hold major radius 12.7 m, minor radius 1.3 m and 15.4 million ampere-turns; the field ceiling stays 24.9 T. The casing wall is 0.025 m on each radial side, so the clear radial cavity is the radial allocation less 0.05 m.

QuantityOriginalCurrent-sizedCurrent-sized, enlarged allocation
Radial allocation / transverse cavity (m)0.30 / 0.400.30 / 0.400.60 / 0.60
Required envelope, radial × transverse (m)0.370 × 0.3790.535 × 0.5480.538 × 0.551
Fit margins, radial / transverse (m)−0.120 / +0.021−0.285 / −0.148+0.012 / +0.049
Peak conductor field (T), limit 24.924.90024.90025.297
Tape length (million m)36.57977.88482.372
Priced magnet subtotal ($ billion)1.7072.5522.695
LCOE ($/MWh)144.747163.194166.744
Checks violateddivertor_heat_ok, reference_conductor_current_ok, wp_fit_okdivertor_heat_ok, wp_fit_okdivertor_heat_ok, peak_field_ok

The study's report records the reference divertor load as 10.52 MW/m² against a 10.0 MW/m² limit, and notes that its priced subtotals carry mixed price bases and unresolved manufacturing scope, so they are conditional estimates, not procurement quotations.

In the study, sizing the conductor supply to carry the required current fixed the current-capacity problem but increased pack size and cost. Enlarging the allocated space fixed the fit problem, but the changed radial geometry raised peak conductor field to 25.30 T, above the retained 24.9 T limit.

The 24.9 T limit is Stellaris's published peak field, held as a ceiling. The model is calibrated so the published design sits exactly on it, so any rise in field fails the check. The field calculation also responds only to coil position and leaves out a term that would lower the field for a larger winding, so the model does not establish which way the real field moves.

Evaluating the connected model shows why fixing one limit does not necessarily produce an acceptable design. Each proposed change must be checked against its effects on the rest of the plant.

2.7.2Map feasibility and cost together

The 17 September neighborhood study exploration/stellarator_e2e/studies/20260917-pre-reveal-feasible-neighborhood/report.md provides the broader radius–current sweep introduced earlier. In the results shown below, major radius and coil ampere-turns vary while the other inputs remain fixed. Each mark represents one evaluated design point.

10.50 10.75 11.00 11.25 11.50 11.75 12.00 Major radius (m) 12.0 12.2 12.4 12.6 12.8 13.0 13.2 Coil ampere-turns (MA-turn) Smaller radius: field limit fails Passing band Larger radius: divertor heat or installed-heating limits fail Feasibility under the 20 modeled screens 10.50 10.75 11.00 11.25 11.50 11.75 12.00 Major radius (m) Cost of electricity at the same points 150 152 154 156 158 160 Conditional LCOE ($/MWh) 44 pass all screens 210 fail at least one screen 2 invalid power accounts
12.0 12.2 12.4 12.6 12.8 13.0 13.2 Coil ampere-turns (MA-turn) Smaller radius: field limit fails Passing band Larger radius: divertor heat or installed-heating limits fail Feasibility, 20 modeled screens 10.5 11.0 11.5 12.0 Major radius (m) 12.0 12.2 12.4 12.6 12.8 13.0 13.2 Coil ampere-turns (MA-turn) Cost of electricity, same points 150 152 154 156 158 160 Conditional LCOE ($/MWh) 44 pass all screens 210 fail at least one screen 2 invalid power accounts
One caseEvery mark is one evaluated case

Each mark is one evaluated case at one major radius and one coil ampere-turn value; the same 256 cases appear in both panels. The record behind each mark holds its inputs, its verdict, the checks it failed, its margins and its conditional cost. The 44 passing cases are circles, the 210 failing cases crosses, and the two invalid power accounts diamonds.

Figure 11This slice contains 256 samples: 44 pass all twenty then-implemented checks with a valid power account, 210 fail at least one check, and two have invalid power accounts. The passing samples span $149.77–152.36/MWh under that snapshot's cost assumptions. Circles identify passing samples in both panels; crosses retain failing results. No feasible region has been interpolated between the points. These samples do not establish a global optimum or the fraction of the whole design space that is feasible. Plot data: archive/write-up/sysml-codegen-assets/feasibility-cost-map.csv.
In the recordHeld inputs for the map

Only radius and coil ampere-turns change among the 256 cases; the extraction that produced the plot data checked this against every case's native input dictionary. The held values:

Held inputValue
Minor radius1.491 m
Peak ion temperature14.036 keV
Peak electron density4.892 × 10²⁰ m⁻³
Density and temperature profile exponents0.35 and 1.2
Representative helium loops18
Radial allocation / transverse cavity0.65 m / 0.65 m
Conductor inventory multiplier (current-driven sizing on)1.01

The remaining defaults are in the study's preparation/resolved-defaults.json. The map is a 256-case fixed-configuration slice of a study with 334 selected cases, of which 103 pass; the two cohorts must not be interchanged. Passing means the twenty screens implemented in that executable passed with a valid power account. At that snapshot the held achieved breeding ratio was 1.074 against a calculated requirement of 1.190, the anchor field exceeded the roughly 24 T extent of the cited conductor measurements, and installed cooling equipment and complete manufacturing were not fully priced.

The passing samples form a narrow band. At fixed ampere-turns, reducing radius increases the modeled field and can violate its limit. Increasing radius reduces field and changes the plasma power balance, eventually running into divertor heat or installed-heating limits. The cost plot explains why minimizing price alone would not answer the design question: low calculated costs also occur at points that fail engineering checks.

This pattern is conditional on the other inputs held fixed for the sweep. The study evidence archive/write-up/sysml-codegen-assets/study-evidence.md, "Held inputs for the radius–current map", summarizes those settings and links to the complete record.

These studies turn design choices into engineering feedback. We can see what a proposed change improves, which limits it violates, and what to investigate next. When that investigation calls for a different component model or additional physics, we revise the model, regenerate the program, and run the next study.

3Sources and figure data