SingleParameterInverseSolveAction

Generates the full fixed-point inverse-solve workflow (forward sub-app, transfers, postprocessors, convergence, and a secant or Newton inversion control) from a single block.

Overview

The SingleParameterInverseSolve action generates a complete fixed-point inverse-solve workflow from a single block, so users do not have to hand-write the coupled MultiApps, Transfers, Postprocessors, Convergence, and Controls blocks.

It recovers a single time-dependent scalar parameter that drives a transient forward model to match a target Function of time. The parameter is genuinely time-dependent, but it can only be recovered at the time steps actually taken: at each step the workflow performs one independent scalar root find for the value that makes the forward output match the target at that step, starting from the previous step's converged value. The recovered history is therefore the sequence of samples , and it depends on the time discretization – because the forward model carries state from one step to the next, refining dt changes the recovered values.

The forward model runs as a transient sub-application (a TransientMultiApp): the matched quantity evolves in time and each step builds on the previous one, so the model must advance step by step and be re-solved for each trial parameter inside the fixed-point (Picard) iteration. The main application drives that loop – it holds the parameter, transfers it down, reads the output back, and updates the parameter through the inversion Control. It may also run its own physics, but need not; the minimal setup only requires a non-empty nonlinear system on the main application.

This is deliberately not framed as an Optimize solve. Optimize derives from Steady: one objective evaluation runs the entire transient, and the full parameter history is recovered simultaneously as a single optimization problem. SingleParameterInverseSolve instead performs one independent one-dimensional root find per time step, nested in the executioner's existing fixed-point (Picard) loop, and needs no additional application instances. The step-by-step approach is applicable whenever the parameter can be recovered one step at a time, which holds when the forward model advances step by step and each step depends only on the parameter at that step.

The method parameter selects the update rule:

commentnote:One per input

SingleParameterInverseSolve is a singular block: at most one may appear per input file, like Executioner or Mesh. It drives the executioner's single multiapp_fixed_point_convergence, so a single input runs exactly one single-parameter inverse solve. To invert for a full parameter vector, use the module's OptimizationReporter / Optimize machinery instead.

Action Behavior

The generated objects are named with a snake_case prefix derived from the block name (the SingleParameterInverseSolve block yields the prefix single_parameter_inverse_solve). The action creates:

commentnote:Generated objects are not user-configurable

The action exposes only the parameters listed on this page. The generated TransientMultiApp, Transfers, Postprocessors, Convergence, and Control are created with fixed settings, so TransientMultiApp options such as sub_cycling, max_procs_per_app, cli_args, catch_up, and keep_solution_during_restore cannot be reached through this block. A workflow that needs them should be written out as explicit blocks rather than generated here.

Required Executioner Parameter

Because the fixed-point loop is enabled when the executioner is constructed (before actions run), one line must remain in the [Executioner] block to enable the loop and point it at the generated convergence:


multiapp_fixed_point_convergence = single_parameter_inverse_solve_convergence

If this line is missing (or points at a different convergence), the action errors during setup with a message telling users exactly how to fix the issue.

Max Iterations Behavior

By default, if the fixed-point loop reaches max_iterations without converging, the solve diverges, the executioner cuts the time step, and (if it cannot) errors. Set accept_on_max_iterations = true to instead accept the current best estimate at max_iterations and continue; this forwards to the generated convergence's converge_at_max_iterations.

Example Input Syntax

# Inverse solve driven by the `SingleParameterInverseSolve` action.
#
# Equivalent to the hand-written secant.i workflow: finds p(t) so the forward output u(t) matches
# target f(t) = t^2. Expected param_value = 1, 3, 5, 7, 9.
#
# The block generates the forward MultiApp, the transfers, the working postprocessors, the
# convergence, and the inversion Control. The only remaining wiring is the one required executioner
# line pointing at the generated convergence.
#
# The tests reuse this input with cli_args to reach the Newton method, the accept-on-max and
# absolute-tolerance paths, and the error raised when the executioner line is wrong.

# Supplies the Mesh and a Problem that skips the nonlinear-system check, so this orchestrating
# main app needs no variables of its own.
[Optimization<<<{"href": "../../syntax/Optimization/index.html"}>>>]
[]

[Functions<<<{"href": "../../syntax/Functions/index.html"}>>>]
  [target_fn]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../functions/MooseParsedFunction.html"}>>>
    expression<<<{"description": "The user defined function."}>>> = 't^2'
  []
[]

[SingleParameterInverseSolve<<<{"href": "../../syntax/SingleParameterInverseSolve/index.html"}>>>]
  method<<<{"description": "Inversion update method."}>>> = secant
  forward_input<<<{"description": "Forward-model sub-app input file."}>>> = forward_linear.i
  sub_parameter_postprocessor<<<{"description": "Sub-app postprocessor that receives the parameter value."}>>> = param_pp
  sub_output_postprocessor<<<{"description": "Sub-app postprocessor holding the output to match the target."}>>> = output_pp
  target_function<<<{"description": "Target output f(t)."}>>> = target_fn
  initial_parameter<<<{"description": "Initial guess for the parameter."}>>> = 1.0
  result_postprocessor<<<{"description": "Name of the created postprocessor holding the converged parameter (output to CSV)."}>>> = param_value
[]

[Executioner<<<{"href": "../../syntax/Executioner/index.html"}>>>]
  type = Transient
  num_steps = 5
  dt = 1
  solve_type = NEWTON
  multiapp_fixed_point_convergence = single_parameter_inverse_solve_convergence
[]

[Outputs<<<{"href": "../../syntax/Outputs/index.html"}>>>]
  csv<<<{"description": "Output the scalar variable and postprocessors to a *.csv file using the default CSV output."}>>> = true
[]
(modules/optimization/test/tests/controls/inverse_solve/action.i)

Input Parameters

  • forward_inputForward-model sub-app input file.

    C++ Type:FileName

    Controllable:No

    Description:Forward-model sub-app input file.

  • sub_output_postprocessorSub-app postprocessor holding the output to match the target.

    C++ Type:PostprocessorName

    Unit:(no unit assumed)

    Controllable:No

    Description:Sub-app postprocessor holding the output to match the target.

  • sub_parameter_postprocessorSub-app postprocessor that receives the parameter value.

    C++ Type:PostprocessorName

    Unit:(no unit assumed)

    Controllable:No

    Description:Sub-app postprocessor that receives the parameter value.

  • target_functionTarget output f(t).

    C++ Type:FunctionName

    Unit:(no unit assumed)

    Controllable:No

    Description:Target output f(t).

Required Parameters

  • absolute_tolerance1e-08Absolute tolerance on |output - target|.

    Default:1e-08

    C++ Type:Real

    Unit:(no unit assumed)

    Range:absolute_tolerance>0

    Controllable:No

    Description:Absolute tolerance on |output - target|.

  • accept_on_max_iterationsFalseIf true, accept the current estimate when the fixed-point loop reaches max_iterations instead of diverging, cutting the time step, and erroring.

    Default:False

    C++ Type:bool

    Controllable:No

    Description:If true, accept the current estimate when the fixed-point loop reaches max_iterations instead of diverging, cutting the time step, and erroring.

  • active__all__ If specified only the blocks named will be visited and made active

    Default:__all__

    C++ Type:std::vector<std::string>

    Controllable:No

    Description:If specified only the blocks named will be visited and made active

  • inactiveIf specified blocks matching these identifiers will be skipped.

    C++ Type:std::vector<std::string>

    Controllable:No

    Description:If specified blocks matching these identifiers will be skipped.

  • initial_parameter1Initial guess for the parameter.

    Default:1

    C++ Type:Real

    Unit:(no unit assumed)

    Controllable:No

    Description:Initial guess for the parameter.

  • max_iterations50Maximum number of fixed-point iterations on the generated convergence. With method=newton each Newton update consumes two fixed-point iterations (a base and a perturbed solve), so the effective number of Newton updates is about half this value.

    Default:50

    C++ Type:unsigned int

    Controllable:No

    Description:Maximum number of fixed-point iterations on the generated convergence. With method=newton each Newton update consumes two fixed-point iterations (a base and a perturbed solve), so the effective number of Newton updates is about half this value.

  • methodsecantInversion update method.

    Default:secant

    C++ Type:MooseEnum

    Options:secant, newton

    Controllable:No

    Description:Inversion update method.

  • perturbation0.001Perturbation used to seed/compute the derivative (initial_delta for secant, parameter_delta for newton).

    Default:0.001

    C++ Type:Real

    Unit:(no unit assumed)

    Range:perturbation>0

    Controllable:No

    Description:Perturbation used to seed/compute the derivative (initial_delta for secant, parameter_delta for newton).

  • relative_tolerance1e-06Relative tolerance on |output - target|, relative to |target|.

    Default:1e-06

    C++ Type:Real

    Unit:(no unit assumed)

    Range:relative_tolerance>0

    Controllable:No

    Description:Relative tolerance on |output - target|, relative to |target|.

  • result_postprocessorinverse_parameterName of the created postprocessor holding the converged parameter (output to CSV).

    Default:inverse_parameter

    C++ Type:PostprocessorName

    Unit:(no unit assumed)

    Controllable:No

    Description:Name of the created postprocessor holding the converged parameter (output to CSV).

  • verboseFalseForwarded to the generated convergence: if true, it prints per-iteration convergence information, including the accept-on-max decision when accept_on_max_iterations is set.

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Forwarded to the generated convergence: if true, it prints per-iteration convergence information, including the accept-on-max decision when accept_on_max_iterations is set.

Optional Parameters

  • control_tagsAdds user-defined labels for accessing object parameters via control logic.

    C++ Type:std::vector<std::string>

    Controllable:No

    Description:Adds user-defined labels for accessing object parameters via control logic.

Advanced Parameters