Cross-referencing

You’ll wire a driver to a model and a model to its tensor inputs by name — the basic glue that lets an input file hold more than one object. Anywhere a field expects an object name, you can write the name of another section in the file.

Referring to a model from a driver

ModelUnitTest is a driver that evaluates a model against a fixed input. Its model option takes the name of a model declared elsewhere in the file:

[Drivers]
  [unit]
    type  = ModelUnitTest
    model = 'elasticity'                  # ← name of the [Models] entry below
    input_SR2_names  = 'strain'
    input_SR2_values = 'strain_value'     # ← name of the [Tensors] entry below
    output_SR2_names = 'stress'
  []
[]

[Tensors]
  [strain_value]
    type = Python
    expr = 'SR2.fill(0.01, 0.0, 0.0, 0.0, 0.0, 0.0)'
  []
[]

[Models]
  [elasticity]
    type = LinearIsotropicElasticity
    coefficients      = '200e3          0.3'
    coefficient_types = 'YOUNGS_MODULUS POISSONS_RATIO'
  []
[]

Two cross-references in one block: model = 'elasticity' names the [Models] entry to evaluate, and input_SR2_values = 'strain_value' names the [Tensors] entry that supplies the input. input_SR2_names and input_SR2_values are parallel lists — one entry per input — and every entry in _values is either a [Tensors] reference or (for Scalar inputs) an inline number.

Other drivers work the same way:

[Drivers]
  [run]
    type  = TransientDriver
    model = 'chaboche_voce_perzyna'                   # ← name of the [Models] entry
    prescribed_time  = 'times'                        # ← name of a [Tensors] entry
    force_SR2_names  = 'E'
    force_SR2_values = 'strains'                      # ← name of a [Tensors] entry
  []
[]

prescribed_time = 'times' is itself a cross-reference — times is the name of a [Tensors] entry. Driving forces are supplied as parallel force_<Type>_names / force_<Type>_values lists, where each value token is again a [Tensors] name (or an inline literal for Scalar).

Referring to a tensor from a model

When a model field expects a tensor value, you can also point it at a [Tensors] entry by name:

[Tensors]
  [E]
    type = Python
    expr = 'Scalar(200e3)'
  []
  [nu]
    type = Python
    expr = 'Scalar(0.3)'
  []
[]

[Models]
  [elasticity]
    type = LinearIsotropicElasticity
    coefficients      = 'E              nu'                # ← refers to [Tensors] entries
    coefficient_types = 'YOUNGS_MODULUS POISSONS_RATIO'
  []
[]

But for simple scalar literals, many model fields accept the number directly — no [Tensors] section needed. (Non-scalar tensor inputs still need a [Tensors] entry.)

[Models]
  [elasticity]
    type = LinearIsotropicElasticity
    coefficients      = '200e3          0.3'               # inline literals
    coefficient_types = 'YOUNGS_MODULUS POISSONS_RATIO'
  []
[]

So when would you go through [Tensors]? When the literal won’t do — typically because you want to share the value across several models, or because it comes from a torch expression like torch.linspace(...) or a CSV file rather than a bare number.

Here’s a temperature-controls axis built from a torch expression:

[Tensors]
  [T_controls]
    type = Python
    expr = 'Scalar.linspace(300.0, 1200.0, 20).sub_batch.retag(1)'
  []
[]

Once declared, every model that references T_controls shares it.

Where to go next

The same name-binding mechanism is what ComposedModel uses to wire its children together — see Model composition.