- topsplitEntrance to splits, the top split will specify how splits will go.C++ Type:std::string Controllable:No Description:Entrance to splits, the top split will specify how splits will go. 
FSP
Preconditioner designed to map onto PETSc's PCFieldSplit.
Overview
The FieldSplitPreconditioner allows for custom preconditioning for each nonlinear variable in the numerical system. One or more variables may be targeted in a subsolve that will only consider part of the numerical system. The preconditioning defined for these subsolves is used for the relevant block(s) in the global numerical system.
A FSP may for example be used for block-diagonal preconditioning by setting full=false and no off-diagonal variable couplings. Numerical systems considering only a single variable are then preconditioned individually. This is the default preconditioner for the PJFNK solves. See the Executioner documentation for more information on the default preconditioner.
More information about field split preconditioning may be found in the PETSc manual.
Example input syntax
In this example, the preconditioning is performed by solving individual problems for each variables, as described in the comments in the snippet. The solution for these subsolves is used to perform the Schur decomposition preconditioning of the main numerical system.
[Preconditioning<<<{"href": "../../syntax/Preconditioning/index.html"}>>>]
  active<<<{"description": "If specified only the blocks named will be visited and made active"}>>> = 'FSP'
  [./FSP]
    type = FSP<<<{"description": "Preconditioner designed to map onto PETSc's PCFieldSplit.", "href": "FieldSplitPreconditioner.html"}>>>
    # It is the starting point of splitting
    topsplit<<<{"description": "Entrance to splits, the top split will specify how splits will go."}>>> = 'uv' # 'uv' should match the following block name
    [./uv]
      splitting = 'u v' # 'u' and 'v' are the names of subsolvers
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      splitting_type = additive
      # An approximate solution to the original system
      # | A_uu  A_uv | | u | _ |f_u|
      # |  0    A_vv | | v | - |f_v|
      #  is obtained by solving the following subsystems
      #  A_uu u = f_u and A_vv v = f_v
      # If splitting type is specified as schur, we may also want to set more options to
      # control how schur works using PETSc options
      # petsc_options_iname = '-pc_fieldsplit_schur_fact_type -pc_fieldsplit_schur_precondition'
      # petsc_options_value = 'full selfp'
    [../]
    [./u]
      vars = 'u'
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    [../]
    [./v]
      vars = 'v'
      # PETSc options for this subsolver
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     lu  preonly'
    [../]
  [../]
[]An example of setting the "off_diag_row" and "off_diag_column" parameters to create a custom coupling matrix may be found in the PBP documentation.
Input Parameters
- fullTrueSet to true if you want the full set of couplings between variables simply for convenience so you don't have to set every off_diag_row and off_diag_column combination.Default:True C++ Type:bool Controllable:No Description:Set to true if you want the full set of couplings between variables simply for convenience so you don't have to set every off_diag_row and off_diag_column combination. 
- ksp_normunpreconditionedSets the norm that is used for convergence testingDefault:unpreconditioned C++ Type:MooseEnum Options:none, preconditioned, unpreconditioned, natural, default Controllable:No Description:Sets the norm that is used for convergence testing 
- nl_sysThe nonlinear system whose linearization this preconditioner should be applied to.C++ Type:NonlinearSystemName Controllable:No Description:The nonlinear system whose linearization this preconditioner should be applied to. 
- off_diag_columnThe variable names for the off-diagonal columns you want to add into the matrix; they will be associated with an off-diagonal row from the same position in off_diag_row.C++ Type:std::vector<NonlinearVariableName> Unit:(no unit assumed) Controllable:No Description:The variable names for the off-diagonal columns you want to add into the matrix; they will be associated with an off-diagonal row from the same position in off_diag_row. 
- off_diag_rowThe variable names for the off-diagonal rows you want to add into the matrix; they will be associated with an off-diagonal column from the same position in off_diag_column.C++ Type:std::vector<NonlinearVariableName> Unit:(no unit assumed) Controllable:No Description:The variable names for the off-diagonal rows you want to add into the matrix; they will be associated with an off-diagonal column from the same position in off_diag_column. 
- pc_sidedefaultPreconditioning sideDefault:default C++ Type:MooseEnum Options:left, right, symmetric, default Controllable:No Description:Preconditioning side 
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. 
- enableTrueSet the enabled status of the MooseObject.Default:True C++ Type:bool Controllable:No Description:Set the enabled status of the MooseObject. 
Advanced Parameters
- mffd_typewpSpecifies the finite differencing type for Jacobian-free solve types. Note that the default is wp (for Walker and Pernice).Default:wp C++ Type:MooseEnum Options:wp, ds Controllable:No Description:Specifies the finite differencing type for Jacobian-free solve types. Note that the default is wp (for Walker and Pernice). 
- petsc_optionsSingleton PETSc optionsC++ Type:MultiMooseEnum Options:-dm_moose_print_embedding, -dm_view, -KSP_CONVERGED_REASON, -KSP_GMRES_MODIFIEDGRAMSCHMIDT, -KSP_MONITOR, -KSP_MONITOR_SNES_LG, -SNES_KSP_EW, -KSP_SNES_EW, -SNES_CONVERGED_REASON, -SNES_KSP, -SNES_LINESEARCH_MONITOR, -SNES_MF, -SNES_MF_OPERATOR, -SNES_MONITOR, -SNES_TEST_DISPLAY, -SNES_VIEW, -SNES_MONITOR_CANCEL Controllable:No Description:Singleton PETSc options 
- petsc_options_inameNames of PETSc name/value pairsC++ Type:MultiMooseEnum Options:-mat_fd_coloring_err, -mat_fd_type, -mat_mffd_type, -pc_asm_overlap, -pc_factor_levels, -pc_factor_mat_ordering_type, -pc_hypre_boomeramg_grid_sweeps_all, -pc_hypre_boomeramg_max_iter, -pc_hypre_boomeramg_strong_threshold, -pc_hypre_type, -pc_type, -sub_pc_type, -KSP_ATOL, -KSP_GMRES_RESTART, -KSP_MAX_IT, -KSP_PC_SIDE, -KSP_RTOL, -KSP_TYPE, -SUB_KSP_TYPE, -SNES_ATOL, -SNES_LINESEARCH_TYPE, -SNES_LS, -SNES_MAX_IT, -SNES_RTOL, -SNES_DIVERGENCE_TOLERANCE, -SNES_TYPE Controllable:No Description:Names of PETSc name/value pairs 
- petsc_options_valueValues of PETSc name/value pairs (must correspond with "petsc_options_iname"C++ Type:std::vector<std::string> Controllable:No Description:Values of PETSc name/value pairs (must correspond with "petsc_options_iname" 
- solve_typePJFNK: Preconditioned Jacobian-Free Newton Krylov JFNK: Jacobian-Free Newton Krylov NEWTON: Full Newton Solve FD: Use finite differences to compute Jacobian LINEAR: Solving a linear problemC++ Type:MooseEnum Options:PJFNK, JFNK, NEWTON, FD, LINEAR Controllable:No Description:PJFNK: Preconditioned Jacobian-Free Newton Krylov JFNK: Jacobian-Free Newton Krylov NEWTON: Full Newton Solve FD: Use finite differences to compute Jacobian LINEAR: Solving a linear problem 
Petsc Parameters
Input Files
- (modules/navier_stokes/test/tests/finite_element/ins/hdg/ip/lid-driven/lid-driven-fsp.i)
- (modules/contact/test/tests/fieldsplit/2blocks3d.i)
- (test/tests/preconditioners/fsp/unside-by-var.i)
- (modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp_stokes.i)
- (test/tests/preconditioners/fsp/vector-test.i)
- (modules/navier_stokes/test/tests/finite_element/ins/lid_driven/transient_fsp.i)
- (test/tests/mortar/periodic_segmental_constraint/penalty_periodic_split.i)
- (test/tests/preconditioners/fsp/penalty-fsp-test.i)
- (test/tests/preconditioners/fsp/missing-var-in-split.i)
- (test/tests/preconditioners/fsp/nested-split.i)
- (python/peacock/tests/input_tab/InputFileEditor/gold/fsp_test.i)
- (test/tests/preconditioners/fsp/array-test.i)
- (test/tests/preconditioners/fsp/fsp_test_image.i)
- (modules/contact/test/tests/fieldsplit/frictionless_mortar_FS.i)
- (python/peacock/tests/input_tab/InputTree/gold/fsp_test.i)
- (modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/2d-rc-no-slip.i)
- (modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp_elman.i)
- (modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp_al.i)
- (modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_fsp_diagonal_of_a_for_scaling.i)
- (modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_fsp.i)
- (modules/contact/test/tests/fieldsplit/frictional_mortar_FS.i)
- (modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp.i)
- (python/peacock/tests/common/fsp_test.i)
- (test/tests/preconditioners/fsp/fsp_test.i)
- (modules/navier_stokes/test/tests/finite_element/ins/pressure_channel/open_bc_pressure_BC_fieldSplit.i)
(test/tests/preconditioners/fsp/fsp_test.i)
[Mesh]
  [./square]
    type = GeneratedMeshGenerator
    nx = 2
    ny = 2
    dim = 2
  [../]
[]
[Variables]
  active = 'u v'
  [./u]
    order = FIRST
    family = LAGRANGE
  [../]
  [./v]
    order = FIRST
    family = LAGRANGE
  [../]
[]
[Kernels]
  active = 'diff_u conv_v diff_v'
  [./diff_u]
    type = Diffusion
    variable = u
  [../]
  [./conv_v]
    type = CoupledForce
    variable = v
    v = u
  [../]
  [./diff_v]
    type = Diffusion
    variable = v
  [../]
[]
[BCs]
  active = 'left_u right_u left_v'
  [./left_u]
    type = DirichletBC
    variable = u
    boundary = 3
    value = 0
  [../]
  [./right_u]
    type = DirichletBC
    variable = u
    boundary = 1
    value = 100
  [../]
  [./left_v]
    type = DirichletBC
    variable = v
    boundary = 3
    value = 0
  [../]
  [./right_v]
    type = DirichletBC
    variable = v
    boundary = 1
    value = 0
  [../]
[]
[Executioner]
  type = Steady
  # This is setup automatically in MOOSE (SetupPBPAction.C)
  # petsc_options = '-snes_mf_operator'
  # petsc_options_iname = '-pc_type'
  # petsc_options_value =  'asm'
[]
[Preconditioning]
  active = 'FSP'
  [./FSP]
    type = FSP
    # It is the starting point of splitting
    topsplit = 'uv' # 'uv' should match the following block name
    [./uv]
      splitting = 'u v' # 'u' and 'v' are the names of subsolvers
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      splitting_type  = additive
      # An approximate solution to the original system
      # | A_uu  A_uv | | u | _ |f_u|
      # |  0    A_vv | | v | - |f_v|
      #  is obtained by solving the following subsystems
      #  A_uu u = f_u and A_vv v = f_v
      # If splitting type is specified as schur, we may also want to set more options to
      # control how schur works using PETSc options
      # petsc_options_iname = '-pc_fieldsplit_schur_fact_type -pc_fieldsplit_schur_precondition'
      # petsc_options_value = 'full selfp'
    [../]
    [./u]
      vars = 'u'
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    [../]
    [./v]
      vars = 'v'
      # PETSc options for this subsolver
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     lu  preonly'
    [../]
  [../]
[]
[Outputs]
  file_base = out
  exodus = true
[]
off_diag_row
C++ Type:std::vector<NonlinearVariableName>
Unit:(no unit assumed)
Controllable:No
Description:The variable names for the off-diagonal rows you want to add into the matrix; they will be associated with an off-diagonal column from the same position in off_diag_column.
off_diag_column
C++ Type:std::vector<NonlinearVariableName>
Unit:(no unit assumed)
Controllable:No
Description:The variable names for the off-diagonal columns you want to add into the matrix; they will be associated with an off-diagonal row from the same position in off_diag_row.
(modules/navier_stokes/test/tests/finite_element/ins/hdg/ip/lid-driven/lid-driven-fsp.i)
mu = 1
rho = 1
l = 1
U = 1e3
n = 200
gamma = 1e5
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    xmin = 0
    xmax = ${l}
    ymin = 0
    ymax = ${l}
    nx = ${n}
    ny = ${n}
    elem_type = TRI6
  []
[]
[Problem]
  type = NavierStokesProblem
  extra_tag_matrices = 'mass'
  mass_matrix = 'mass'
  use_pressure_mass_matrix = true
[]
[Variables]
  [vel_x]
    family = MONOMIAL
    order = FIRST
  []
  [vel_y]
    family = MONOMIAL
    order = FIRST
  []
  [pressure]
    family = MONOMIAL
    order = CONSTANT
  []
  [vel_bar_x]
    family = SIDE_HIERARCHIC
    order = FIRST
  []
  [vel_bar_y]
    family = SIDE_HIERARCHIC
    order = FIRST
  []
  [pressure_bar]
    family = SIDE_HIERARCHIC
    order = FIRST
  []
[]
[HDGKernels]
  [momentum_x_convection]
    type = AdvectionIPHDGKernel
    variable = vel_x
    face_variable = vel_bar_x
    velocity = 'velocity'
    coeff = ${rho}
  []
  [momentum_x_diffusion]
    type = NavierStokesStressIPHDGKernel
    variable = vel_x
    face_variable = vel_bar_x
    diffusivity = 'mu'
    alpha = 6
    pressure_variable = pressure
    pressure_face_variable = pressure_bar
    component = 0
  []
  [momentum_y_convection]
    type = AdvectionIPHDGKernel
    variable = vel_y
    face_variable = vel_bar_y
    velocity = 'velocity'
    coeff = ${rho}
  []
  [momentum_y_diffusion]
    type = NavierStokesStressIPHDGKernel
    variable = vel_y
    face_variable = vel_bar_y
    diffusivity = 'mu'
    alpha = 6
    pressure_variable = pressure
    pressure_face_variable = pressure_bar
    component = 1
  []
  [pressure_convection]
    type = AdvectionIPHDGKernel
    variable = pressure
    face_variable = pressure_bar
    velocity = 'velocity'
    coeff = '${fparse -rho}'
    self_advection = false
  []
[]
[Kernels]
  [mass_matrix_pressure]
    type = MassMatrix
    variable = pressure
    matrix_tags = 'mass'
    density = '${fparse -1/gamma}'
  []
  [grad_div_x]
    type = GradDiv
    variable = vel_x
    u = vel_x
    v = vel_y
    gamma = ${gamma}
    component = 0
  []
  [grad_div_y]
    type = GradDiv
    variable = vel_y
    u = vel_x
    v = vel_y
    gamma = ${gamma}
    component = 1
  []
[]
[DGKernels]
  [pb_mass]
    type = MassMatrixDGKernel
    variable = pressure_bar
    matrix_tags = 'mass'
    density = '${fparse -1/gamma}'
  []
  [u_jump]
    type = MassFluxPenalty
    variable = vel_x
    u = vel_x
    v = vel_y
    component = 0
    gamma = ${gamma}
  []
  [v_jump]
    type = MassFluxPenalty
    variable = vel_y
    u = vel_x
    v = vel_y
    component = 1
    gamma = ${gamma}
  []
[]
[BCs]
  [momentum_x_diffusion_walls]
    type = NavierStokesStressIPHDGDirichletBC
    boundary = 'left bottom right'
    variable = vel_x
    face_variable = vel_bar_x
    pressure_variable = pressure
    pressure_face_variable = pressure_bar
    alpha = 6
    functor = '0'
    diffusivity = 'mu'
    component = 0
  []
  [momentum_x_diffusion_top]
    type = NavierStokesStressIPHDGDirichletBC
    boundary = 'top'
    variable = vel_x
    face_variable = vel_bar_x
    pressure_variable = pressure
    pressure_face_variable = pressure_bar
    alpha = 6
    functor = '${U}'
    diffusivity = 'mu'
    component = 0
  []
  [momentum_y_diffusion_all]
    type = NavierStokesStressIPHDGDirichletBC
    boundary = 'left bottom right top'
    variable = vel_y
    face_variable = vel_bar_y
    pressure_variable = pressure
    pressure_face_variable = pressure_bar
    alpha = 6
    functor = '0'
    diffusivity = 'mu'
    component = 1
  []
  [mass_convection]
    type = AdvectionIPHDGPrescribedFluxBC
    face_variable = pressure_bar
    variable = pressure
    velocity = 'velocity'
    coeff = '${fparse -rho}'
    self_advection = false
    boundary = 'left bottom top right'
    prescribed_normal_flux = 0
  []
  [pb_mass]
    type = MassMatrixIntegratedBC
    variable = pressure_bar
    matrix_tags = 'mass'
    boundary = 'left right bottom top'
    density = '${fparse -1/gamma}'
  []
  [u_jump_walls]
    type = MassFluxPenaltyBC
    variable = vel_x
    u = vel_x
    v = vel_y
    component = 0
    boundary = 'left right bottom'
    gamma = ${gamma}
    dirichlet_value = 'walls'
  []
  [v_jump_walls]
    type = MassFluxPenaltyBC
    variable = vel_y
    u = vel_x
    v = vel_y
    component = 1
    boundary = 'left right bottom'
    gamma = ${gamma}
    dirichlet_value = 'walls'
  []
  [u_jump_top]
    type = MassFluxPenaltyBC
    variable = vel_x
    u = vel_x
    v = vel_y
    component = 0
    boundary = 'top'
    gamma = ${gamma}
    dirichlet_value = 'top'
  []
  [v_jump_top]
    type = MassFluxPenaltyBC
    variable = vel_y
    u = vel_x
    v = vel_y
    component = 1
    boundary = 'top'
    gamma = ${gamma}
    dirichlet_value = 'top'
  []
[]
[Functions]
  [top]
    type = ParsedVectorFunction
    value_x = ${U}
    value_y = 0
  []
  [walls]
    type = ParsedVectorFunction
    value_x = 0
    value_y = 0
  []
[]
[Materials]
  [const]
    type = ADGenericConstantMaterial
    prop_names = 'rho mu'
    prop_values = '${rho} ${mu}'
  []
  [vel]
    type = ADVectorFromComponentVariablesMaterial
    vector_prop_name = 'velocity'
    u = vel_x
    v = vel_y
  []
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'up'
    [up]
      splitting = 'u p'
      splitting_type = schur
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_type -ksp_pc_side -ksp_rtol'
      petsc_options_value = 'full                            self                              300                fgmres    right        1e-4'
    []
    [u]
      vars = 'vel_x vel_y vel_bar_x vel_bar_y'
      petsc_options = '-ksp_converged_reason'
      petsc_options_iname = '-pc_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side -pc_factor_mat_solver_type'
      petsc_options_value = 'ilu      gmres     1e-2      300                right        strumpack'
    []
    [p]
      vars = 'pressure pressure_bar'
      petsc_options = '-ksp_converged_reason'
      petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side'
      petsc_options_value = 'gmres     300                1e-2      ilu      right'
    []
  []
[]
[Executioner]
  type = Steady
  solve_type = 'NEWTON'
[]
[Outputs]
  active = ''
  [out]
    type = Exodus
    hide = 'pressure_average vel_bar_x vel_bar_y pressure_bar'
  []
[]
[Postprocessors]
  [Re]
    type = ParsedPostprocessor
    pp_names = ''
    expression = '${rho} * ${U} * ${l} / ${mu}'
  []
  [pressure_average]
    type = ElementAverageValue
    variable = pressure
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = pressure
    pressure_average = 'pressure_average'
  []
[]
(modules/contact/test/tests/fieldsplit/2blocks3d.i)
[GlobalParams]
  displacements = 'disp_x disp_y disp_z'
  volumetric_locking_correction = true
[]
[Mesh]
  file = 2blocks3d.e
  patch_size = 5
[]
[Problem]
  error_on_jacobian_nonzero_reallocation = true
[]
[Physics/SolidMechanics/QuasiStatic]
  [./all]
    strain = FINITE
    incremental = true
    add_variables = true
  [../]
[]
[AuxVariables]
  [./penetration]
    order = FIRST
    family = LAGRANGE
  [../]
[]
[Functions]
  [./horizontal_movement]
    type = ParsedFunction
    expression = t/10.0
  [../]
[]
[AuxKernels]
  [./penetration]
    type = PenetrationAux
    variable = penetration
    boundary = 2
    paired_boundary = 3
    order = FIRST
  [../]
[]
[BCs]
  [./push_x]
    type = FunctionDirichletBC
    variable = disp_x
    boundary = 1
    function = horizontal_movement
  [../]
  [./fix_x]
    type = DirichletBC
    variable = disp_x
    boundary = 4
    value = 0.0
  [../]
  [./fix_y]
    type = DirichletBC
    variable = disp_y
    boundary = '1 4'
    value = 0.0
  [../]
  [./fix_z]
    type = DirichletBC
    variable = disp_z
    boundary = '1 4'
    value = 0.0
  [../]
[]
[Materials]
  [./elasticity_tensor_left]
    type = ComputeIsotropicElasticityTensor
    block = 1
    youngs_modulus = 1.0e6
    poissons_ratio = 0.3
  [../]
  [./stress_left]
    type = ComputeFiniteStrainElasticStress
    block = 1
  [../]
  [./elasticity_tensor_right]
    type = ComputeIsotropicElasticityTensor
    block = 2
    youngs_modulus = 1.0e6
    poissons_ratio = 0.3
  [../]
  [./stress_right]
    type = ComputeFiniteStrainElasticStress
    block = 2
  [../]
[]
[Contact]
  [./leftright]
    secondary = 2
    primary = 3
    model = frictionless
    penalty = 1e+6
    normalize_penalty = true
    formulation = kinematic
    normal_smoothing_distance = 0.1
  [../]
[]
[Preconditioning]
  [./FSP]
    type = FSP
    # It is the starting point of splitting
    topsplit = 'contact_interior' # 'contact_interior' should match the following block name
    [./contact_interior]
      splitting          = 'contact interior'
      splitting_type     = multiplicative
    [../]
    [./interior]
      type = ContactSplit
      vars = 'disp_x disp_y disp_z'
      uncontact_primary   = '3'
      uncontact_secondary    = '2'
      uncontact_displaced = '1'
      blocks              = '1 2'
      include_all_contact_nodes = 1
      petsc_options_iname = '-ksp_type -pc_type -pc_hypre_type -pc_hypre_boomeramg_max_iter -pc_hypre_boomeramg_strong_threshold'
      petsc_options_value = 'preonly   hypre    boomeramg      1                            0.25'
    [../]
    [./contact]
      type = ContactSplit
      vars = 'disp_x disp_y disp_z'
      contact_primary   = '3'
      contact_secondary    = '2'
      contact_displaced = '1'
      include_all_contact_nodes = 1
      petsc_options_iname = '-ksp_type -pc_type -pc_asm_overlap -sub_pc_type'
      petsc_options_value = 'preonly   asm      1               lu'
    [../]
  [../]
[]
[Executioner]
  type = Transient
  solve_type = 'PJFNK'
  dt = 0.1
  dtmin = 0.1
  end_time = 0.1
  l_tol = 1e-4
  l_max_its = 100
  nl_rel_tol = 1e-10
  nl_abs_tol = 1e-6
  nl_max_its = 100
[]
[Outputs]
  file_base = 2blocks3d_out
  [./exodus]
    type = Exodus
  [../]
  [./console]
    type = Console
    max_rows = 5
  [../]
[]
(test/tests/preconditioners/fsp/unside-by-var.i)
[Mesh]
  [square]
    type = GeneratedMeshGenerator
    nx = 2
    ny = 2
    dim = 2
  []
[]
[Variables]
  [u][]
  [v][]
[]
[Kernels]
  [diff_u]
    type = Diffusion
    variable = u
  []
  [conv_v]
    type = CoupledForce
    variable = v
    v = u
  []
  [diff_v]
    type = Diffusion
    variable = v
  []
[]
[BCs]
  [left_u]
    type = DirichletBC
    variable = u
    boundary = 3
    value = 0
  []
  [right_u]
    type = DirichletBC
    variable = u
    boundary = 1
    value = 100
  []
  [left_v]
    type = DirichletBC
    variable = v
    boundary = 3
    value = 0
  []
  [right_v]
    type = DirichletBC
    variable = v
    boundary = 1
    value = 0
  []
[]
[Executioner]
  type = Steady
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'top'
    [top]
      splitting = 'u_diri rest'
      splitting_type  = multiplicative
      petsc_options_iname = '-ksp_type'
      petsc_options_value = 'fgmres'
    []
      [u_diri]
        vars = 'u'
        sides = 'left right'
      []
      [rest]
        unside_by_var_var_name = 'u u'
        unside_by_var_boundary_name = 'left right'
      []
  []
[]
[Outputs]
  exodus = true
[]
(modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp_stokes.i)
rho=1
mu=1
U=1
l=1
prefactor=${fparse 1/(l/2)^2}
n=8
[Mesh]
  [gen]
    type = DistributedRectilinearMeshGenerator
    dim = 2
    xmin = 0
    xmax = ${l}
    ymin = 0
    ymax = ${l}
    nx = ${n}
    ny = ${n}
    elem_type = QUAD4
  []
  second_order = true
  parallel_type = distributed
[]
[Variables]
  [vel]
    order = SECOND
    family = LAGRANGE_VEC
  []
  [p]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [mass]
    type = INSADMass
    variable = p
  []
  [mass_kernel]
    type = MassMatrix
    variable = p
    matrix_tags = 'mass'
  []
  [momentum_viscous]
    type = INSADMomentumViscous
    variable = vel
  []
  [momentum_pressure]
    type = INSADMomentumPressure
    variable = vel
    pressure = p
    integrate_p_by_parts = true
  []
[]
[BCs]
  [no_slip]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'bottom right left'
  []
  [lid]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'top'
    function_x = 'lid_function'
  []
[]
[Materials]
  [const]
    type = ADGenericConstantMaterial
    prop_names = 'rho mu'
    prop_values = '${rho} ${mu}'
  []
  [insad]
    type = INSADMaterial
    velocity = vel
    pressure = p
  []
[]
[Functions]
  [lid_function]
    # We pick a function that is exactly represented in the velocity
    # space so that the Dirichlet conditions are the same regardless
    # of the mesh spacing.
    type = ParsedFunction
    expression = '${prefactor}*${U}*x*(${l}-x)'
  []
[]
[Problem]
  type = NavierStokesProblem
  mass_matrix = 'mass'
  extra_tag_matrices = 'mass'
  use_pressure_mass_matrix = true
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'up'
    [up]
      splitting = 'u p'
      splitting_type  = schur
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_type -ksp_pc_side -ksp_rtol'
      petsc_options_value = 'full                            self                              300                fgmres    right        1e-4'
    []
      [u]
        vars = 'vel'
        # petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-pc_type -pc_hypre_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side'
        petsc_options_value = 'hypre    boomeramg      gmres     1e-2      300                right'
      []
      [p]
        vars = 'p'
        petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side -pc_hypre_type'
        petsc_options_value = 'fgmres    300                1e-2      hypre    right        boomeramg'
      []
  []
[]
[Postprocessors]
  [pavg]
    type = ElementAverageValue
    variable = p
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = p
    pressure_average = 'pavg'
  []
[]
[Executioner]
  type = Steady
  solve_type = NEWTON
  nl_rel_tol = 1e-12
[]
[Outputs]
  print_linear_residuals = false
  [exo]
    type = Exodus
    execute_on = 'final'
    hide = 'pavg'
  []
[]
(test/tests/preconditioners/fsp/vector-test.i)
[Mesh]
  type = GeneratedMesh
  nx = 5
  ny = 5
  dim = 2
[]
[Variables]
  [u]
    family = LAGRANGE_VEC
  []
  [v]
    family = LAGRANGE_VEC
  []
[]
[Kernels]
  [time_u]
    type = VectorTimeDerivative
    variable = u
  []
  [fn_u]
    type = VectorBodyForce
    variable = u
    function_x = 1
    function_y = 1
  []
  [time_v]
    type = VectorCoupledTimeDerivative
    variable = v
    v = u
  []
  [diff_v]
    type = VectorDiffusion
    variable = v
  []
[]
[BCs]
  [left]
    type = VectorDirichletBC
    variable = v
    boundary = 'left'
    values = '0 0 0'
  []
  [right]
    type = VectorDirichletBC
    variable = v
    boundary = 'right'
    values = '1 1 0'
  []
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'uv'
    [uv]
      splitting = 'u v'
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      splitting_type  = symmetric_multiplicative
    []
    [u]
      vars = 'u'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    []
    [v]
      vars = 'v'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre  preonly'
    []
  []
[]
[Executioner]
  type = Transient
  num_steps = 1
  solve_type = 'NEWTON'
[]
[Outputs]
  exodus = true
[]
(modules/navier_stokes/test/tests/finite_element/ins/lid_driven/transient_fsp.i)
n=64
mu=2e-3
[GlobalParams]
  gravity = '0 0 0'
  preset = true
  supg = false
[]
[Problem]
  extra_tag_matrices = 'mass'
  previous_nl_solution_required = true
  type = NavierStokesProblem
  mass_matrix = 'mass'
  schur_fs_index = '1'
[]
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    xmin = 0
    xmax = 1.0
    ymin = 0
    ymax = 1.0
    nx = ${n}
    ny = ${n}
    elem_type = QUAD9
  []
[]
[Variables]
  [vel_x]
    order = SECOND
    family = LAGRANGE
  []
  [vel_y]
    order = SECOND
    family = LAGRANGE
  []
  [p]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  # mass
  [mass]
    type = INSMass
    variable = p
    u = vel_x
    v = vel_y
    pressure = p
  []
  [x_time]
    type = INSMomentumTimeDerivative
    variable = vel_x
  []
  [x_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_x
    u = vel_x
    v = vel_y
    pressure = p
    component = 0
  []
  [x_mass]
    type = MassMatrix
    variable = vel_x
    matrix_tags = 'mass'
  []
  [y_time]
    type = INSMomentumTimeDerivative
    variable = vel_y
  []
  [y_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_y
    u = vel_x
    v = vel_y
    pressure = p
    component = 1
  []
  [y_mass]
    type = MassMatrix
    variable = vel_y
    matrix_tags = 'mass'
  []
[]
[BCs]
  [x_no_slip]
    type = DirichletBC
    variable = vel_x
    boundary = 'bottom right left'
    value = 0.0
  []
  [lid]
    type = FunctionDirichletBC
    variable = vel_x
    boundary = 'top'
    function = 'lid_function'
  []
  [y_no_slip]
    type = DirichletBC
    variable = vel_y
    boundary = 'bottom right top left'
    value = 0.0
  []
[]
[Materials]
  [const]
    type = GenericConstantMaterial
    block = 0
    prop_names = 'rho mu'
    prop_values = '1  ${mu}'
  []
[]
[Functions]
  [lid_function]
    # We pick a function that is exactly represented in the velocity
    # space so that the Dirichlet conditions are the same regardless
    # of the mesh spacing.
    type = ParsedFunction
    expression = '4*x*(1-x)'
  []
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'by_diri_others'
    [by_diri_others]
      splitting = 'diri others'
      splitting_type  = additive
      petsc_options_iname = '-ksp_type'
      petsc_options_value = 'preonly'
    []
      [diri]
        sides = 'left right top bottom'
        vars = 'vel_x vel_y'
        petsc_options_iname = '-pc_type'
        petsc_options_value = 'jacobi'
      []
      [others]
        splitting = 'u p'
        splitting_type  = schur
        petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_rtol -ksp_type -ksp_atol'
        petsc_options_value = 'full                            self                              300                1e-5      fgmres    1e-9'
        unside_by_var_boundary_name = 'left top right bottom left top right bottom'
        unside_by_var_var_name = 'vel_x vel_x vel_x vel_x vel_y vel_y vel_y vel_y'
      []
        [u]
          vars = 'vel_x vel_y'
          unside_by_var_boundary_name = 'left top right bottom left top right bottom'
          unside_by_var_var_name = 'vel_x vel_x vel_x vel_x vel_y vel_y vel_y vel_y'
          # petsc_options = '-ksp_converged_reason'
          petsc_options_iname = '-pc_type -ksp_pc_side -ksp_type -ksp_rtol -pc_hypre_type -ksp_gmres_restart'
          petsc_options_value = 'hypre    right        gmres     1e-2      boomeramg      300'
        []
        [p]
          vars = 'p'
          petsc_options = '-pc_lsc_scale_diag -ksp_converged_reason'# -lsc_ksp_converged_reason -lsc_ksp_monitor_true_residual
          petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side -lsc_pc_type -lsc_pc_hypre_type -lsc_ksp_type -lsc_ksp_rtol -lsc_ksp_pc_side -lsc_ksp_gmres_restart'
          petsc_options_value = 'fgmres    300                1e-2      lsc      right        hypre        boomeramg          gmres         1e-1          right            300'
        []
  []
[]
[Postprocessors]
  [pavg]
    type = ElementAverageValue
    variable = p
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = p
    pressure_average = 'pavg'
  []
[]
[Executioner]
  solve_type = NEWTON
  type = Transient
  petsc_options_iname = '-snes_max_it'
  petsc_options_value = '100'
  line_search = 'none'
  nl_rel_tol = 1e-8
  nl_abs_tol = 1e-9
  abort_on_solve_fail = true
  normalize_solution_diff_norm_by_dt = false
  [TimeStepper]
    type = IterationAdaptiveDT
    optimal_iterations = 6
    dt = 1e-2
  []
  steady_state_detection = true
[]
[Outputs]
  [exo]
    type = Exodus
    execute_on = 'final'
    hide = 'pavg'
  []
[]
(test/tests/mortar/periodic_segmental_constraint/penalty_periodic_split.i)
[Mesh]
  [left_block]
    type = GeneratedMeshGenerator
    dim = 3
    xmin = -3.0
    xmax = 3.0
    ymin = -3.0
    ymax = 3.0
    zmin = -3.0
    zmax = 3.0
    nx = 3
    ny = 3
    nz = 3
    elem_type = HEX8
  []
  [left_block_sidesets]
    type = RenameBoundaryGenerator
    input = left_block
    old_boundary = '0 1 2 3 4 5'
    new_boundary = '10 11 12 13 14 15'
  []
  [left_block_id]
    type = SubdomainIDGenerator
    input = left_block_sidesets
    subdomain_id = 1
  []
  [left]
    type = LowerDBlockFromSidesetGenerator
    input = left_block_id
    sidesets = '14'
    new_block_id = '10004'
    new_block_name = 'secondary_left'
  []
  [right]
    type = LowerDBlockFromSidesetGenerator
    input = left
    sidesets = '12'
    new_block_id = '10002'
    new_block_name = 'primary_right'
  []
  [bottom]
    type = LowerDBlockFromSidesetGenerator
    input = right
    sidesets = '10'
    new_block_id = '10000'
    new_block_name = 'secondary_bottom'
  []
  [top]
    type = LowerDBlockFromSidesetGenerator
    input = bottom
    sidesets = '15'
    new_block_id = '10005'
    new_block_name = 'primary_top'
  []
  [back]
    type = LowerDBlockFromSidesetGenerator
    input = top
    sidesets = '11'
    new_block_id = '10001'
    new_block_name = 'secondary_back'
  []
  [front]
    type = LowerDBlockFromSidesetGenerator
    input = back
    sidesets = '13'
    new_block_id = '10003'
    new_block_name = 'primary_front'
  []
  [corner_node]
    type = ExtraNodesetGenerator
    new_boundary = 'pinned_node'
    nodes = '0'
    input = front
  []
[]
[Variables]
  [u]
    order = FIRST
    family = LAGRANGE
  []
  [epsilon]
    order = THIRD
    family = SCALAR
  []
[]
[AuxVariables]
  [sigma]
    order = THIRD
    family = SCALAR
  []
[]
[AuxScalarKernels]
  [sigma]
    type = FunctionScalarAux
    variable = sigma
    function = '1 2 3'
    execute_on = initial #timestep_end
  []
[]
[Kernels]
  [diff1]
    type = Diffusion
    variable = u
    block = 1
  []
[]
[Problem]
  kernel_coverage_check = false
  error_on_jacobian_nonzero_reallocation = true
[]
[BCs]
  [fix_right]
    type = DirichletBC
    variable = u
    boundary = pinned_node
    value = 0
  []
[]
[Constraints]
  [mortarlr]
    type = PenaltyEqualValueConstraint
    primary_boundary = '12'
    secondary_boundary = '14'
    primary_subdomain = 'primary_right'
    secondary_subdomain = 'secondary_left'
    secondary_variable = u
    correct_edge_dropping = true
    penalty_value = 1.e2
  []
  [periodiclr]
    type = PenaltyPeriodicSegmentalConstraint
    primary_boundary = '12'
    secondary_boundary = '14'
    primary_subdomain = 'primary_right'
    secondary_subdomain = 'secondary_left'
    secondary_variable = u
    epsilon = epsilon
    sigma = sigma
    correct_edge_dropping = true
    penalty_value = 1.e2
  []
  [mortarbt]
    type = PenaltyEqualValueConstraint
    primary_boundary = '15'
    secondary_boundary = '10'
    primary_subdomain = 'primary_top'
    secondary_subdomain = 'secondary_bottom'
    secondary_variable = u
    correct_edge_dropping = true
    penalty_value = 1.e2
  []
  [periodicbt]
    type = PenaltyPeriodicSegmentalConstraint
    primary_boundary = '15'
    secondary_boundary = '10'
    primary_subdomain = 'primary_top'
    secondary_subdomain = 'secondary_bottom'
    secondary_variable = u
    epsilon = epsilon
    sigma = sigma
    correct_edge_dropping = true
    penalty_value = 1.e2
  []
  [mortarbf]
    type = PenaltyEqualValueConstraint
    primary_boundary = '13'
    secondary_boundary = '11'
    primary_subdomain = 'primary_front'
    secondary_subdomain = 'secondary_back'
    secondary_variable = u
    correct_edge_dropping = true
    penalty_value = 1.e2
  []
  [periodicbf]
    type = PenaltyPeriodicSegmentalConstraint
    primary_boundary = '13'
    secondary_boundary = '11'
    primary_subdomain = 'primary_front'
    secondary_subdomain = 'secondary_back'
    secondary_variable = u
    epsilon = epsilon
    sigma = sigma
    correct_edge_dropping = true
    penalty_value = 1.e2
  []
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'uv' # 'uv' should match the following block name
    [uv]
      splitting = 'u v' # 'u' and 'v' are the names of subsolvers
      splitting_type = additive
    []
    [u]
      vars = 'u'
      petsc_options_iname = '-ksp_gmres_restart -pc_type -pc_hypre_type -pc_hypre_boomeramg_max_iter'
      petsc_options_value = '  201               hypre    boomeramg      10'
    []
    [v]
      vars = 'epsilon'
      petsc_options_iname = '-ksp_type -pc_type -pc_hypre_type -pc_hypre_boomeramg_max_iter'
      petsc_options_value = ' preonly   hypre    boomeramg      10'
    []
  []
[]
[Executioner]
  type = Steady
  solve_type = NEWTON
[]
[Outputs]
  csv = true
[]
(test/tests/preconditioners/fsp/penalty-fsp-test.i)
[Mesh]
  [square]
    type = GeneratedMeshGenerator
    nx = 10
    ny = 10
    dim = 2
  []
  second_order = true
[]
[Variables]
  [u]
    order = SECOND
  []
  [v]
    order = SECOND
  []
[]
[Kernels]
  [diff_u]
    type = Diffusion
    variable = u
  []
  [conv_v]
    type = CoupledForce
    variable = v
    v = u
  []
  [diff_v]
    type = Diffusion
    variable = v
  []
[]
[BCs]
  [left_u]
    type = PenaltyDirichletBC
    penalty = 1e6
    variable = u
    boundary = 3
    value = 0
  []
  [right_u]
    type = PenaltyDirichletBC
    penalty = 1e6
    variable = u
    boundary = 1
    value = 100
  []
  [left_v]
    type = PenaltyDirichletBC
    penalty = 1e6
    variable = v
    boundary = 3
    value = 0
  []
  [right_v]
    type = PenaltyDirichletBC
    penalty = 1e6
    variable = v
    boundary = 1
    value = 0
  []
[]
[Executioner]
  type = Steady
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'uv'
    [uv]
      splitting = 'u v'
      splitting_type = additive
    []
    [u]
      vars = 'u'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    []
    [v]
      vars = 'v'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     lu  preonly'
    []
  []
[]
[Outputs]
  exodus = true
[]
(test/tests/preconditioners/fsp/missing-var-in-split.i)
[Mesh]
  [square]
    type = GeneratedMeshGenerator
    nx = 2
    ny = 2
    dim = 2
  []
[]
[Variables]
  [u][]
  [v][]
  [w][]
[]
[Kernels]
  [diff_u]
    type = Diffusion
    variable = u
  []
  [diff_v]
    type = Diffusion
    variable = v
  []
  [diff_w]
    type = Diffusion
    variable = w
  []
[]
[BCs]
  [left_u]
    type = DirichletBC
    variable = u
    boundary = 3
    value = 0
  []
  [right_u]
    type = DirichletBC
    variable = u
    boundary = 1
    value = 100
  []
  [left_v]
    type = DirichletBC
    variable = v
    boundary = 3
    value = 0
  []
  [right_v]
    type = DirichletBC
    variable = v
    boundary = 1
    value = 0
  []
  [left_w]
    type = DirichletBC
    variable = w
    boundary = 3
    value = 0
  []
  [right_w]
    type = DirichletBC
    variable = w
    boundary = 1
    value = 0
  []
[]
[Executioner]
  type = Steady
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'uv'
    [uv]
      splitting = 'u v'
      splitting_type  = additive
    []
    [u]
      vars = 'u'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    []
    [v]
      vars = 'v'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre  preonly'
    []
  []
[]
(test/tests/preconditioners/fsp/nested-split.i)
[Mesh]
  [square]
    type = GeneratedMeshGenerator
    nx = 2
    ny = 2
    dim = 2
  []
[]
[Variables]
  [u][]
  [v][]
[]
[Kernels]
  [diff_u]
    type = Diffusion
    variable = u
  []
  [conv_v]
    type = CoupledForce
    variable = v
    v = u
  []
  [diff_v]
    type = Diffusion
    variable = v
  []
[]
[BCs]
  [left_u]
    type = DirichletBC
    variable = u
    boundary = 3
    value = 0
  []
  [right_u]
    type = DirichletBC
    variable = u
    boundary = 1
    value = 100
  []
  [left_v]
    type = DirichletBC
    variable = v
    boundary = 3
    value = 0
  []
  [right_v]
    type = DirichletBC
    variable = v
    boundary = 1
    value = 0
  []
[]
[Executioner]
  type = Steady
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'by_var'
    [by_var]
      splitting = 'u v'
      splitting_type  = multiplicative
      petsc_options_iname = '-ksp_type'
      petsc_options_value = 'fgmres'
    []
      [u]
        vars = 'u'
        splitting = 'u_diri u_bulk'
        splitting_type = multiplicative
        petsc_options_iname = '-ksp_type'
        petsc_options_value = 'fgmres'
      []
        [u_diri]
          vars = 'u'
          petsc_options = '-ksp_view_pmat'
          sides = 'left right'
        []
        [u_bulk]
          vars = 'u'
          petsc_options = '-ksp_view_pmat'
          petsc_options_iname = '-ksp_type'
          petsc_options_value = 'cg'
          unsides = 'left right'
        []
      [v]
        vars = 'v'
        splitting = 'v_diri v_bulk'
        splitting_type = multiplicative
        petsc_options_iname = '-ksp_type'
        petsc_options_value = 'fgmres'
      []
        [v_diri]
          vars = 'v'
          petsc_options = '-ksp_view_pmat'
          sides = 'left right'
        []
        [v_bulk]
          vars = 'v'
          petsc_options = '-ksp_view_pmat'
          petsc_options_iname = '-ksp_type'
          petsc_options_value = 'cg'
          unsides = 'left right'
        []
  []
[]
[Outputs]
  exodus = true
[]
(python/peacock/tests/input_tab/InputFileEditor/gold/fsp_test.i)
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 2
  ny = 2
[]
[Variables]
  [u]
    order = FIRST
    family = LAGRANGE
  []
  [v]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [diff_u]
    type = Diffusion
    variable = u
  []
  [conv_v]
    type = CoupledForce
    variable = v
    v = 'u'
  []
  [diff_v]
    type = Diffusion
    variable = v
  []
[]
[BCs]
  inactive = 'right_v'
  [left_u]
    type = DirichletBC
    variable = u
    boundary = '1'
    value = 0
  []
  [right_u]
    type = DirichletBC
    variable = u
    boundary = '2'
    value = 100
  []
  [left_v]
    type = DirichletBC
    variable = v
    boundary = '1'
    value = 0
  []
  [right_v]
    type = DirichletBC
    variable = v
    boundary = '2'
    value = 0
  []
[]
[Executioner]
  # This is setup automatically in MOOSE (SetupPBPAction.C)
  # petsc_options = '-snes_mf_operator'
  # petsc_options_iname = '-pc_type'
  # petsc_options_value =  'asm'
  type = Steady
[]
[Preconditioning]
  [FSP]
    # It is the starting point of splitting
    type = FSP
    topsplit = 'uv' # uv should match the following block name
    [uv]
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      # An approximate solution to the original system
      # | A_uu  A_uv | | u | _ |f_u|
      # |  0    A_vv | | v | - |f_v|
      # is obtained by solving the following subsystems
      # A_uu u = f_u and A_vv v = f_v
      # If splitting type is specified as schur, we may also want to set more options to
      # control how schur works using PETSc options
      # petsc_options_iname = '-pc_fieldsplit_schur_fact_type -pc_fieldsplit_schur_precondition'
      # petsc_options_value = 'full selfp'
      splitting = 'u v' # u and v are the names of subsolvers
      splitting_type = additive
    []
    [u]
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      vars = 'u'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    []
    [v]
      # PETSc options for this subsolver
      vars = 'v'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre  preonly'
    []
  []
[]
[Outputs]
  file_base = out
  exodus = true
[]
(test/tests/preconditioners/fsp/array-test.i)
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 4
  ny = 4
[]
[Variables]
  [u]
    order = FIRST
    family = LAGRANGE
    components = 2
  []
  [v]
  []
[]
[Kernels]
  [diff]
    type = ArrayDiffusion
    variable = u
    diffusion_coefficient = dc
  []
  [reaction]
    type = ArrayReaction
    variable = u
    reaction_coefficient = rc
  []
  [diffv]
    type = Diffusion
    variable = v
  []
  [vu]
    type = ArrayCoupledForce
    variable = u
    v = v
    coef = '0 0.5'
  []
[]
[BCs]
  [left]
    type = ArrayDirichletBC
    variable = u
    boundary = 1
    values = '0 0'
  []
  [right]
    type = ArrayDirichletBC
    variable = u
    boundary = 2
    values = '1 2'
  []
  [leftv]
    type = DirichletBC
    variable = v
    boundary = 1
    value = 0
  []
  [rightv]
    type = DirichletBC
    variable = v
    boundary = 2
    value = 2
  []
[]
[Materials]
  [dc]
    type = GenericConstantArray
    prop_name = dc
    prop_value = '1 1'
  []
  [rc]
    type = GenericConstant2DArray
    prop_name = rc
    prop_value = '1 0; -0.1 1'
  []
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'uv'
    [uv]
      splitting = 'u v'
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      splitting_type  = symmetric_multiplicative
    []
    [u]
      vars = 'u'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    []
    [v]
      vars = 'v'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre  preonly'
    []
  []
[]
[Postprocessors]
  [intu0]
    type = ElementIntegralArrayVariablePostprocessor
    variable = u
    component = 0
  []
  [intu1]
    type = ElementIntegralArrayVariablePostprocessor
    variable = u
    component = 1
  []
  [intv]
    type = ElementIntegralVariablePostprocessor
    variable = v
  []
[]
[Executioner]
  type = Steady
  solve_type = 'NEWTON'
[]
[Outputs]
  exodus = true
[]
(test/tests/preconditioners/fsp/fsp_test_image.i)
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    nx = 41
    ny = 41
  []
  [./image]
    input = gen
    type = ImageSubdomainGenerator
    file = kitten.png
    threshold = 100
  [../]
[]
[Variables]
  [./u]
    order = FIRST
    family = LAGRANGE
    block = 1
  [../]
  [./v]
    order = FIRST
    family = LAGRANGE
    block = 1
  [../]
[]
[Kernels]
  [./diff_u]
    type = Diffusion
    variable = u
  [../]
  [./conv_v]
    type = CoupledForce
    variable = v
    v = u
  [../]
  [./diff_v]
    type = Diffusion
    variable = v
  [../]
[]
[BCs]
  active = 'left_u left_v right_u'
  [./left_u]
    type = DirichletBC
    variable = u
    boundary = left
    value = 0
  [../]
  [./right_u]
    type = DirichletBC
    variable = u
    boundary = right
    value = 100
  [../]
  [./left_v]
    type = DirichletBC
    variable = v
    boundary = left
    value = 0
  [../]
  [./right_v]
    type = DirichletBC
    variable = v
    boundary = right
    value = 0
  [../]
[]
[Problem]
  type = FEProblem
  material_coverage_check = false
  kernel_coverage_check = false
[]
[Executioner]
  # This is setup automatically in MOOSE (SetupPBPAction.C)
  # petsc_options = '-snes_mf_operator'
  # petsc_options_iname = '-pc_type'
  # petsc_options_value =  'asm'
  type = Steady
[]
[Preconditioning]
  [./FSP]
    # It is the starting point of splitting
    type = FSP
    topsplit = 'uv' # 'uv'
    [./uv]
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      # An approximate solution to the original system
      # | A_uu  A_uv | | u | _ |f_u|
      # |  0    A_vv | | v | - |f_v|
      # is obtained by solving the following subsystems
      # A_uu u = f_u and A_vv v = f_v
      # If splitting type is specified as schur, we may also want to set more options to
      # control how schur works using PETSc options
      # petsc_options_iname = '-pc_fieldsplit_schur_fact_type -pc_fieldsplit_schur_precondition'
      # petsc_options_value = 'full selfp'
      splitting = 'u v' # 'u' and 'v'
      splitting_type = additive
    [../]
    [./u]
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      vars = u
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    [../]
    [./v]
      # PETSc options for this subsolver
      vars = v
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre  preonly'
    [../]
  [../]
[]
[Outputs]
  file_base = kitten_out
  exodus = true
[]
(modules/contact/test/tests/fieldsplit/frictionless_mortar_FS.i)
offset = 0.021
vy = 0.15
vx = 0.04
refine = 1
[GlobalParams]
  displacements = 'disp_x disp_y'
  volumetric_locking_correction = true
[]
[Mesh]
  [original_file_mesh]
    type = FileMeshGenerator
    file = long_short_blocks.e
  []
  uniform_refine = ${refine}
[]
[Physics/SolidMechanics/QuasiStatic]
  [all]
    strain = FINITE
    incremental = true
    add_variables = true
    block = '1 2'
    use_automatic_differentiation = true
  []
[]
[Functions]
  [horizontal_movement]
    type = ParsedFunction
    value = 'if(t<0.5,${vx}*t-${offset},${vx}-${offset})'
  []
  [vertical_movement]
    type = ParsedFunction
    value = 'if(t<0.5,${offset},${vy}*(t-0.5)+${offset})'
  []
[]
[BCs]
  [push_left_x]
    type = FunctionDirichletBC
    variable = disp_x
    boundary = 30
    function = horizontal_movement
    preset = false
  []
  [fix_right_x]
    type = DirichletBC
    variable = disp_x
    boundary = 40
    value = 0.0
  []
  [fix_right_y]
    type = DirichletBC
    variable = disp_y
    boundary = '40'
    value = 0.0
  []
  [push_left_y]
    type = FunctionDirichletBC
    variable = disp_y
    boundary = '30'
    function = vertical_movement
    preset = false
  []
[]
[Materials]
  [elasticity_tensor_left]
    type = ADComputeIsotropicElasticityTensor
    block = 1
    youngs_modulus = 1.0e6
    poissons_ratio = 0.3
  []
  [stress_left]
    type = ADComputeFiniteStrainElasticStress
    block = 1
  []
  [elasticity_tensor_right]
    type = ADComputeIsotropicElasticityTensor
    block = 2
    youngs_modulus = 1.0e6
    poissons_ratio = 0.3
  []
  [stress_right]
    type = ADComputeFiniteStrainElasticStress
    block = 2
  []
[]
[Contact]
  [leftright]
    secondary = 10
    primary = 20
    model = frictionless
    formulation = mortar
    c_normal = 1e6
  []
[]
[ICs]
  [disp_y]
    block = 1
    variable = disp_y
    value = ${offset}
    type = ConstantIC
  []
  [disp_x]
    block = 1
    variable = disp_x
    value = -${offset}
    type = ConstantIC
  []
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'contact_interior'
    [contact_interior]
      splitting = 'interior contact'
      splitting_type = schur
      petsc_options = '-snes_ksp_ew'
      petsc_options_iname = '-ksp_gmres_restart -pc_fieldsplit_schur_fact_type -mat_mffd_err'
      petsc_options_value = '200                full                           1e-5'
      schur_pre = 'S'
    []
    [interior]
      vars = 'disp_x disp_y'
      petsc_options_iname = '-ksp_type -pc_type -pc_hypre_type '
      petsc_options_value = 'gmres   hypre  boomeramg'
    []
    [contact]
      vars = 'leftright_normal_lm'
    []
  []
[]
[Executioner]
  type = Transient
  solve_type = 'PJFNK'
  dt = 0.1
  end_time = 1
  abort_on_solve_fail = true
  l_max_its = 200
  nl_abs_tol = 1e-8
  line_search = 'none'
  nl_max_its = 20
[]
[Outputs]
  exodus = true
[]
[Postprocessors]
  [lin]
    type = NumLinearIterations
    outputs = 'console'
  []
  [cum]
    type = CumulativeValuePostprocessor
    postprocessor = 'lin'
    outputs = 'console'
  []
[]
(python/peacock/tests/input_tab/InputTree/gold/fsp_test.i)
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 2
  ny = 2
[]
[Variables]
  [u]
    order = FIRST
    family = LAGRANGE
  []
  [v]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [diff_u]
    type = Diffusion
    variable = u
  []
  [conv_v]
    type = CoupledForce
    variable = v
    v = 'u'
  []
  [diff_v]
    type = Diffusion
    variable = v
  []
[]
[BCs]
  inactive = 'right_v'
  [left_u]
    type = DirichletBC
    variable = u
    boundary = '1'
    value = 0
  []
  [right_u]
    type = DirichletBC
    variable = u
    boundary = '2'
    value = 100
  []
  [left_v]
    type = DirichletBC
    variable = v
    boundary = '1'
    value = 0
  []
  [right_v]
    type = DirichletBC
    variable = v
    boundary = '2'
    value = 0
  []
[]
[Executioner]
  # This is setup automatically in MOOSE (SetupPBPAction.C)
  # petsc_options = '-snes_mf_operator'
  # petsc_options_iname = '-pc_type'
  # petsc_options_value =  'asm'
  type = Steady
[]
[Preconditioning]
  [FSP]
    # It is the starting point of splitting
    type = FSP
    topsplit = 'uv' # uv should match the following block name
    [uv]
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      # An approximate solution to the original system
      # | A_uu  A_uv | | u | _ |f_u|
      # |  0    A_vv | | v | - |f_v|
      # is obtained by solving the following subsystems
      # A_uu u = f_u and A_vv v = f_v
      # If splitting type is specified as schur, we may also want to set more options to
      # control how schur works using PETSc options
      # petsc_options_iname = '-pc_fieldsplit_schur_fact_type -pc_fieldsplit_schur_precondition'
      # petsc_options_value = 'full selfp'
      splitting = 'u v' # u and v are the names of subsolvers
      splitting_type = additive
    []
    [u]
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      symbol_names = 'u'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    []
    [v]
      # PETSc options for this subsolver
      symbol_names = 'v'
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre  preonly'
    []
  []
[]
[Outputs]
  file_base = out
  exodus = true
[]
(modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/2d-rc-no-slip.i)
mu = 1.1
rho = 1.1
l = 2
U = 1
advected_interp_method = 'average'
velocity_interp_method = 'rc'
[GlobalParams]
  rhie_chow_user_object = 'rc'
[]
[UserObjects]
  [rc]
    type = INSFVRhieChowInterpolator
    u = vel_x
    v = vel_y
    pressure = pressure
  []
[]
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    xmin = 0
    xmax = 10
    ymin = ${fparse -l / 2}
    ymax = ${fparse l / 2}
    nx = 100
    ny = 20
  []
  uniform_refine = 0
[]
[Variables]
  [vel_x]
    type = INSFVVelocityVariable
    initial_condition = 1
  []
  [vel_y]
    type = INSFVVelocityVariable
    initial_condition = 1
  []
  [pressure]
    type = INSFVPressureVariable
  []
[]
[FVKernels]
  [mass]
    type = INSFVMassAdvection
    variable = pressure
    advected_interp_method = ${advected_interp_method}
    velocity_interp_method = ${velocity_interp_method}
    rho = ${rho}
  []
  [u_advection]
    type = INSFVMomentumAdvection
    variable = vel_x
    advected_interp_method = ${advected_interp_method}
    velocity_interp_method = ${velocity_interp_method}
    rho = ${rho}
    momentum_component = 'x'
  []
  [u_viscosity]
    type = INSFVMomentumDiffusion
    variable = vel_x
    mu = ${mu}
    momentum_component = 'x'
  []
  [u_pressure]
    type = INSFVMomentumPressure
    variable = vel_x
    momentum_component = 'x'
    pressure = pressure
  []
  [v_advection]
    type = INSFVMomentumAdvection
    variable = vel_y
    advected_interp_method = ${advected_interp_method}
    velocity_interp_method = ${velocity_interp_method}
    rho = ${rho}
    momentum_component = 'y'
  []
  [v_viscosity]
    type = INSFVMomentumDiffusion
    variable = vel_y
    mu = ${mu}
    momentum_component = 'y'
  []
  [v_pressure]
    type = INSFVMomentumPressure
    variable = vel_y
    momentum_component = 'y'
    pressure = pressure
  []
[]
[FVBCs]
  [inlet-u]
    type = INSFVInletVelocityBC
    boundary = 'left'
    variable = vel_x
    function = '${U}'
  []
  [inlet-v]
    type = INSFVInletVelocityBC
    boundary = 'left'
    variable = vel_y
    function = '0'
  []
  [walls-u]
    type = INSFVNoSlipWallBC
    boundary = 'top bottom'
    variable = vel_x
    function = 0
  []
  [walls-v]
    type = INSFVNoSlipWallBC
    boundary = 'top bottom'
    variable = vel_y
    function = 0
  []
  [outlet_p]
    type = INSFVOutletPressureBC
    boundary = 'right'
    variable = pressure
    function = '0'
  []
[]
[Executioner]
  type = Steady
  solve_type = 'NEWTON'
  nl_rel_tol = 1e-12
[]
[Preconditioning]
  active = FSP
  [FSP]
    type = FSP
    # It is the starting point of splitting
    topsplit = 'up' # 'up' should match the following block name
    [up]
      splitting = 'u p' # 'u' and 'p' are the names of subsolvers
      splitting_type  = schur
      # Splitting type is set as schur, because the pressure part of Stokes-like systems
      # is not diagonally dominant. CAN NOT use additive, multiplicative and etc.
      #
      # Original system:
      #
      # | Auu Aup | | u | = | f_u |
      # | Apu 0   | | p |   | f_p |
      #
      # is factorized into
      #
      # |I             0 | | Auu  0|  | I  Auu^{-1}*Aup | | u | = | f_u |
      # |Apu*Auu^{-1}  I | | 0   -S|  | 0  I            | | p |   | f_p |
      #
      # where
      #
      # S = Apu*Auu^{-1}*Aup
      #
      # The preconditioning is accomplished via the following steps
      #
      # (1) p* = f_p - Apu*Auu^{-1}f_u,
      # (2) p = (-S)^{-1} p*
      # (3) u = Auu^{-1}(f_u-Aup*p)
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_rtol -ksp_type'
      petsc_options_value = 'full                            selfp                             300                1e-4      fgmres'
    []
    [u]
      vars = 'vel_x vel_y'
      petsc_options_iname = '-pc_type -pc_hypre_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side'
      petsc_options_value = 'hypre    boomeramg      gmres    5e-1      300                 right'
    []
    [p]
      vars = 'pressure'
      petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side'
      petsc_options_value = 'gmres    300                5e-1      jacobi    right'
    []
  []
  [SMP]
    type = SMP
    full = true
    petsc_options_iname = '-pc_type -pc_factor_shift_type'
    petsc_options_value = 'lu       NONZERO'
  []
[]
[Outputs]
  print_linear_residuals = true
  print_nonlinear_residuals = true
  [out]
    type = Exodus
    hide = 'Re lin cum_lin'
  []
  [perf]
    type = PerfGraphOutput
  []
[]
[Postprocessors]
  [Re]
    type = ParsedPostprocessor
    expression = '${rho} * ${l} * ${U}'
  []
  [lin]
    type = NumLinearIterations
  []
  [cum_lin]
    type = CumulativeValuePostprocessor
    postprocessor = lin
  []
[]
(modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp_elman.i)
rho=1
mu=1
U=1
l=1
prefactor=${fparse 1/(l/2)^2}
n=8
[Mesh]
  [gen]
    type = DistributedRectilinearMeshGenerator
    dim = 2
    xmin = 0
    xmax = ${l}
    ymin = 0
    ymax = ${l}
    nx = ${n}
    ny = ${n}
    elem_type = QUAD4
  []
  second_order = true
  parallel_type = distributed
[]
[Variables]
  [vel]
    order = SECOND
    family = LAGRANGE_VEC
  []
  [p]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [mass]
    type = INSADMass
    variable = p
  []
  [velocity_mass_kernel]
    type = VectorMassMatrix
    variable = vel
    matrix_tags = 'mass'
  []
  [momentum_convection]
    type = INSADMomentumAdvection
    variable = vel
  []
  [momentum_viscous]
    type = INSADMomentumViscous
    variable = vel
  []
  [momentum_pressure]
    type = INSADMomentumPressure
    variable = vel
    pressure = p
    integrate_p_by_parts = true
  []
[]
[BCs]
  [no_slip]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'bottom right left'
  []
  [lid]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'top'
    function_x = 'lid_function'
  []
[]
[Materials]
  [const]
    type = ADGenericConstantMaterial
    prop_names = 'rho mu'
    prop_values = '${rho} ${mu}'
  []
  [insad]
    type = INSADMaterial
    velocity = vel
    pressure = p
  []
[]
[Functions]
  [lid_function]
    # We pick a function that is exactly represented in the velocity
    # space so that the Dirichlet conditions are the same regardless
    # of the mesh spacing.
    type = ParsedFunction
    expression = '${prefactor}*${U}*x*(${l}-x)'
  []
[]
[Problem]
  type = NavierStokesProblem
  mass_matrix = 'mass'
  extra_tag_matrices = 'mass'
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'up'
    [up]
      splitting = 'u p'
      splitting_type  = schur
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_type -ksp_pc_side -ksp_rtol'
      petsc_options_value = 'full                            self                              300                fgmres    right        1e-4'
    []
      [u]
        vars = 'vel'
        # petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-pc_type -pc_hypre_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side'
        petsc_options_value = 'hypre    boomeramg      gmres     1e-2      300                right'
      []
      [p]
        vars = 'p'
        petsc_options = '-ksp_converged_reason -pc_lsc_scale_diag'
        petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side -lsc_pc_type -lsc_pc_hypre_type -lsc_ksp_type -lsc_ksp_rtol -lsc_ksp_pc_side -lsc_ksp_gmres_restart'
        petsc_options_value = 'fgmres    300                1e-2      lsc      right        hypre        boomeramg          gmres         1e-1          right            300'
      []
  []
[]
[Postprocessors]
  [pavg]
    type = ElementAverageValue
    variable = p
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = p
    pressure_average = 'pavg'
  []
[]
[Executioner]
  type = Steady
  solve_type = NEWTON
[]
[Outputs]
  print_linear_residuals = false
  [exo]
    type = Exodus
    execute_on = 'final'
    hide = 'pavg'
  []
[]
(modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp_al.i)
rho=1
mu=1e-3
U=1
l=1
prefactor=${fparse 1/(l/2)^2}
n=8
gamma=${U}
[Mesh]
  [gen]
    type = GeneratedMeshGenerator
    dim = 2
    xmin = 0
    xmax = ${l}
    ymin = 0
    ymax = ${l}
    nx = ${n}
    ny = ${n}
    elem_type = QUAD4
  []
  second_order = true
[]
[Variables]
  [vel]
    order = SECOND
    family = LAGRANGE_VEC
  []
  [p]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [mass]
    type = INSADMass
    variable = p
  []
  [mass_kernel]
    type = MassMatrix
    variable = p
    matrix_tags = 'mass'
    density = ${fparse -1/(gamma + mu)}
  []
  [momentum_advection]
    type = INSADMomentumAdvection
    variable = vel
  []
  [momentum_viscous]
    type = INSADMomentumViscous
    variable = vel
  []
  [momentum_pressure]
    type = INSADMomentumPressure
    variable = vel
    pressure = p
    integrate_p_by_parts = true
  []
  [momentum_graddiv]
    type = INSADMomentumGradDiv
    variable = vel
    gamma = ${gamma}
  []
[]
[BCs]
  [no_slip]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'bottom right left'
    preset = true
  []
  [lid]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'top'
    function_x = 'lid_function'
    preset = true
  []
[]
[Materials]
  [const]
    type = ADGenericConstantMaterial
    prop_names = 'rho mu'
    prop_values = '${rho} ${mu}'
  []
  [insad]
    type = INSADTauMaterial
    velocity = vel
    pressure = p
  []
[]
[Functions]
  [lid_function]
    # We pick a function that is exactly represented in the velocity
    # space so that the Dirichlet conditions are the same regardless
    # of the mesh spacing.
    type = ParsedFunction
    expression = '${prefactor}*${U}*x*(${l}-x)'
  []
[]
[Problem]
  type = NavierStokesProblem
  mass_matrix = 'mass'
  extra_tag_matrices = 'mass'
  use_pressure_mass_matrix = true
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'up'
    [up]
      splitting = 'u p'
      splitting_type  = schur
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_type -ksp_pc_side -ksp_rtol'
      petsc_options_value = 'full                            self                              300                fgmres    right        1e-4'
    []
      [u]
        vars = 'vel'
        petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-pc_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side -pc_factor_mat_solver_type'
        petsc_options_value = 'ilu      gmres     1e-2      300                right        strumpack'
      []
      [p]
        vars = 'p'
        petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side'
        petsc_options_value = 'gmres     300                1e-2      ilu      right'
      []
  []
[]
[Postprocessors]
  [pavg]
    type = ElementAverageValue
    variable = p
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = p
    pressure_average = 'pavg'
  []
[]
[Executioner]
  type = Steady
  solve_type = NEWTON
  nl_rel_tol = 1e-12
[]
[Outputs]
  print_linear_residuals = false
  [exo]
    type = Exodus
    execute_on = 'final'
    hide = 'pavg'
  []
[]
(modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_fsp_diagonal_of_a_for_scaling.i)
rho=1
mu=2e-3
U=1
l=1
prefactor=${fparse 1/(l/2)^2}
n=64
[GlobalParams]
  gravity = '0 0 0'
[]
[Mesh]
  [gen]
    type = DistributedRectilinearMeshGenerator
    dim = 2
    xmin = 0
    xmax = ${l}
    ymin = 0
    ymax = ${l}
    nx = ${n}
    ny = ${n}
    elem_type = QUAD4
  []
  second_order = true
  parallel_type = distributed
[]
[Variables]
  [vel_x]
    order = SECOND
    family = LAGRANGE
  []
  [vel_y]
    order = SECOND
    family = LAGRANGE
  []
  [p]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [mass]
    type = INSMass
    variable = p
    u = vel_x
    v = vel_y
    pressure = p
  []
  [x_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_x
    u = vel_x
    v = vel_y
    pressure = p
    component = 0
  []
  [y_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_y
    u = vel_x
    v = vel_y
    pressure = p
    component = 1
  []
[]
[BCs]
  [x_no_slip]
    type = DirichletBC
    variable = vel_x
    boundary = 'bottom right left'
    value = 0.0
  []
  [lid]
    type = FunctionDirichletBC
    variable = vel_x
    boundary = 'top'
    function = 'lid_function'
  []
  [y_no_slip]
    type = DirichletBC
    variable = vel_y
    boundary = 'bottom right top left'
    value = 0.0
  []
[]
[Materials]
  [const]
    type = GenericConstantMaterial
    block = 0
    prop_names = 'rho mu'
    prop_values = '${rho} ${mu}'
  []
[]
[Functions]
  [lid_function]
    # We pick a function that is exactly represented in the velocity
    # space so that the Dirichlet conditions are the same regardless
    # of the mesh spacing.
    type = ParsedFunction
    expression = '${prefactor}*${U}*x*(${l}-x)'
  []
[]
[Problem]
  type = NavierStokesProblem
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'up'
    [up]
      splitting = 'u p'
      splitting_type  = schur
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_type -ksp_pc_side -ksp_rtol'
      petsc_options_value = 'full                            self                              300                fgmres    right        1e-4'
    []
      [u]
        vars = 'vel_x vel_y'
        # petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-pc_type -pc_hypre_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side'
        petsc_options_value = 'hypre    boomeramg      gmres     1e-2      300                right'
      []
      [p]
        vars = 'p'
        petsc_options = '-pc_lsc_scale_diag -ksp_converged_reason'# -lsc_ksp_converged_reason -lsc_ksp_monitor_true_residual
        petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side -lsc_pc_type -lsc_pc_hypre_type -lsc_ksp_type -lsc_ksp_rtol -lsc_ksp_pc_side -lsc_ksp_gmres_restart'
        petsc_options_value = 'fgmres    300                1e-2      lsc      right        hypre        boomeramg          gmres         1e-1          right            300'
      []
  []
[]
[Postprocessors]
  [pavg]
    type = ElementAverageValue
    variable = p
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = p
    pressure_average = 'pavg'
  []
[]
[Executioner]
  type = Steady
  solve_type = NEWTON
[]
[Outputs]
  [exo]
    type = Exodus
    execute_on = 'final'
    hide = 'pavg'
  []
[]
(modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_fsp.i)
rho=1
mu=2e-3
U=1
l=1
prefactor=${fparse 1/(l/2)^2}
n=64
[GlobalParams]
  gravity = '0 0 0'
[]
[Mesh]
  [gen]
    type = DistributedRectilinearMeshGenerator
    dim = 2
    xmin = 0
    xmax = ${l}
    ymin = 0
    ymax = ${l}
    nx = ${n}
    ny = ${n}
    elem_type = QUAD4
  []
  second_order = true
  parallel_type = distributed
[]
[Variables]
  [vel_x]
    order = SECOND
    family = LAGRANGE
  []
  [vel_y]
    order = SECOND
    family = LAGRANGE
  []
  [p]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [mass]
    type = INSMass
    variable = p
    u = vel_x
    v = vel_y
    pressure = p
  []
  [x_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_x
    u = vel_x
    v = vel_y
    pressure = p
    component = 0
  []
  [momentum_x_mass]
    type = MassMatrix
    variable = vel_x
    density = ${rho}
    matrix_tags = 'mass'
  []
  [y_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_y
    u = vel_x
    v = vel_y
    pressure = p
    component = 1
  []
  [momentum_y_mass]
    type = MassMatrix
    variable = vel_y
    density = ${rho}
    matrix_tags = 'mass'
  []
[]
[BCs]
  [x_no_slip]
    type = DirichletBC
    variable = vel_x
    boundary = 'bottom right left'
    value = 0.0
  []
  [lid]
    type = FunctionDirichletBC
    variable = vel_x
    boundary = 'top'
    function = 'lid_function'
  []
  [y_no_slip]
    type = DirichletBC
    variable = vel_y
    boundary = 'bottom right top left'
    value = 0.0
  []
[]
[Materials]
  [const]
    type = GenericConstantMaterial
    block = 0
    prop_names = 'rho mu'
    prop_values = '${rho} ${mu}'
  []
[]
[Functions]
  [lid_function]
    # We pick a function that is exactly represented in the velocity
    # space so that the Dirichlet conditions are the same regardless
    # of the mesh spacing.
    type = ParsedFunction
    expression = '${prefactor}*${U}*x*(${l}-x)'
  []
[]
[Problem]
  type = NavierStokesProblem
  mass_matrix = 'mass'
  extra_tag_matrices = 'mass'
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'up'
    [up]
      splitting = 'u p'
      splitting_type  = schur
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_type -ksp_pc_side -ksp_rtol'
      petsc_options_value = 'full                            self                              300                fgmres    right        1e-4'
    []
      [u]
        vars = 'vel_x vel_y'
        # petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-pc_type -pc_hypre_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side'
        petsc_options_value = 'hypre    boomeramg      gmres     1e-2      300                right'
      []
      [p]
        vars = 'p'
        petsc_options = '-pc_lsc_scale_diag -ksp_converged_reason'# -lsc_ksp_converged_reason -lsc_ksp_monitor_true_residual
        petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side -lsc_pc_type -lsc_pc_hypre_type -lsc_ksp_type -lsc_ksp_rtol -lsc_ksp_pc_side -lsc_ksp_gmres_restart'
        petsc_options_value = 'fgmres    300                1e-2      lsc      right        hypre        boomeramg          gmres         1e-1          right            300'
      []
  []
[]
[Postprocessors]
  [pavg]
    type = ElementAverageValue
    variable = p
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = p
    pressure_average = 'pavg'
  []
[]
[Executioner]
  type = Steady
  solve_type = NEWTON
[]
[Outputs]
  [exo]
    type = Exodus
    execute_on = 'final'
    hide = 'pavg'
  []
[]
(modules/contact/test/tests/fieldsplit/frictional_mortar_FS.i)
offset = 0.021
vy = 0.15
vx = 0.04
refine = 1
[GlobalParams]
  displacements = 'disp_x disp_y'
  volumetric_locking_correction = true
[]
[Mesh]
  [original_file_mesh]
    type = FileMeshGenerator
    file = long_short_blocks.e
  []
  uniform_refine = ${refine}
[]
[Physics/SolidMechanics/QuasiStatic]
  [all]
    strain = FINITE
    incremental = true
    add_variables = true
    block = '1 2'
    use_automatic_differentiation = true
  []
[]
[Functions]
  [horizontal_movement]
    type = ParsedFunction
    expression = 'if(t<0.5,${vx}*t-${offset},${vx}-${offset})'
  []
  [vertical_movement]
    type = ParsedFunction
    expression = 'if(t<0.5,${offset},${vy}*(t-0.5)+${offset})'
  []
[]
[BCs]
  [push_left_x]
    type = FunctionDirichletBC
    variable = disp_x
    boundary = 30
    function = horizontal_movement
    preset = false
  []
  [fix_right_x]
    type = DirichletBC
    variable = disp_x
    boundary = 40
    value = 0.0
  []
  [fix_right_y]
    type = DirichletBC
    variable = disp_y
    boundary = '40'
    value = 0.0
  []
  [push_left_y]
    type = FunctionDirichletBC
    variable = disp_y
    boundary = '30'
    function = vertical_movement
    preset = false
  []
[]
[Materials]
  [elasticity_tensor_left]
    type = ADComputeIsotropicElasticityTensor
    block = 1
    youngs_modulus = 1.0e6
    poissons_ratio = 0.3
  []
  [stress_left]
    type = ADComputeFiniteStrainElasticStress
    block = 1
  []
  [elasticity_tensor_right]
    type = ADComputeIsotropicElasticityTensor
    block = 2
    youngs_modulus = 1.0e6
    poissons_ratio = 0.3
  []
  [stress_right]
    type = ADComputeFiniteStrainElasticStress
    block = 2
  []
[]
[Contact]
  [leftright]
    secondary = 10
    primary = 20
    model = coulomb
    friction_coefficient = 0.2
    formulation = mortar
    c_normal = 1e5
    c_tangential = 1e4
  []
[]
[ICs]
  [disp_y]
    block = 1
    variable = disp_y
    value = ${offset}
    type = ConstantIC
  []
  [disp_x]
    block = 1
    variable = disp_x
    value = -${offset}
    type = ConstantIC
  []
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'contact_interior'
    [contact_interior]
      splitting = 'interior contact'
      splitting_type = schur
      petsc_options = '-snes_ksp_ew'
      petsc_options_iname = '-ksp_gmres_restart -pc_fieldsplit_schur_fact_type -mat_mffd_err'
      petsc_options_value = '200                full                           1e-5'
      schur_pre = 'S'
    []
    [interior]
      vars = 'disp_x disp_y'
      petsc_options_iname = '-ksp_type -pc_type -pc_hypre_type '
      petsc_options_value = 'gmres   hypre  boomeramg'
    []
    [contact]
      vars = 'leftright_normal_lm leftright_tangential_lm'
    []
  []
[]
[Executioner]
  type = Transient
  solve_type = 'PJFNK'
  dt = 0.1
  end_time = 1
  abort_on_solve_fail = true
  l_max_its = 200
  nl_abs_tol = 1e-8
  line_search = 'none'
  nl_max_its = 20
[]
[Outputs]
  exodus = true
[]
(modules/navier_stokes/test/tests/finite_element/ins/lid_driven/steady_vector_fsp.i)
rho=1
mu=1
U=1
l=1
prefactor=${fparse 1/(l/2)^2}
n=8
[Mesh]
  [gen]
    type = DistributedRectilinearMeshGenerator
    dim = 2
    xmin = 0
    xmax = ${l}
    ymin = 0
    ymax = ${l}
    nx = ${n}
    ny = ${n}
    elem_type = QUAD4
  []
  second_order = true
  parallel_type = distributed
[]
[Variables]
  [vel]
    order = SECOND
    family = LAGRANGE_VEC
  []
  [p]
    order = FIRST
    family = LAGRANGE
  []
[]
[Kernels]
  [mass]
    type = INSADMass
    variable = p
  []
  [mass_kernel]
    type = MassMatrix
    variable = p
    matrix_tags = 'mass'
  []
  [momentum_convection]
    type = INSADMomentumAdvection
    variable = vel
  []
  [momentum_viscous]
    type = INSADMomentumViscous
    variable = vel
    extra_matrix_tags = 'L'
  []
  [momentum_pressure]
    type = INSADMomentumPressure
    variable = vel
    pressure = p
    integrate_p_by_parts = true
  []
[]
[BCs]
  [no_slip]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'bottom right left'
    extra_matrix_tags = 'L'
  []
  [lid]
    type = ADVectorFunctionDirichletBC
    variable = vel
    boundary = 'top'
    function_x = 'lid_function'
    extra_matrix_tags = 'L'
  []
[]
[Materials]
  [const]
    type = ADGenericConstantMaterial
    prop_names = 'rho mu'
    prop_values = '${rho} ${mu}'
  []
  [insad]
    type = INSADMaterial
    velocity = vel
    pressure = p
  []
[]
[Functions]
  [lid_function]
    # We pick a function that is exactly represented in the velocity
    # space so that the Dirichlet conditions are the same regardless
    # of the mesh spacing.
    type = ParsedFunction
    expression = '${prefactor}*${U}*x*(${l}-x)'
  []
[]
[Problem]
  type = NavierStokesProblem
  mass_matrix = 'mass'
  extra_tag_matrices = 'mass L'
  L_matrix = 'L'
  commute_lsc = true
[]
[Preconditioning]
  [FSP]
    type = FSP
    topsplit = 'up'
    [up]
      splitting = 'u p'
      splitting_type  = schur
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition -ksp_gmres_restart -ksp_type -ksp_pc_side -ksp_rtol'
      petsc_options_value = 'full                            self                              300                fgmres    right        1e-4'
    []
      [u]
        vars = 'vel'
        # petsc_options = '-ksp_converged_reason'
        petsc_options_iname = '-pc_type -pc_hypre_type -ksp_type -ksp_rtol -ksp_gmres_restart -ksp_pc_side'
        petsc_options_value = 'hypre    boomeramg      gmres     1e-2      300                right'
      []
      [p]
        vars = 'p'
        petsc_options = '-ksp_converged_reason -pc_lsc_commute'
        petsc_options_iname = '-ksp_type -ksp_gmres_restart -ksp_rtol -pc_type -ksp_pc_side -lsc_pc_type -lsc_pc_hypre_type -lsc_ksp_type -lsc_ksp_rtol -lsc_ksp_pc_side -lsc_ksp_gmres_restart -lsc_mass_pc_type -lsc_mass_pc_hypre_type -lsc_mass_ksp_rtol -lsc_mass_ksp_type'
        petsc_options_value = 'fgmres    300                1e-2      lsc      right        hypre        boomeramg          fgmres         1e-1         right            300                    hypre             boomeramg               1e-1               gmres'
      []
  []
[]
[Postprocessors]
  [pavg]
    type = ElementAverageValue
    variable = p
  []
[]
[Correctors]
  [set_pressure]
    type = NSPressurePin
    pin_type = 'average'
    variable = p
    pressure_average = 'pavg'
  []
[]
[Executioner]
  type = Steady
  solve_type = NEWTON
[]
[Outputs]
  print_linear_residuals = false
  [exo]
    type = Exodus
    execute_on = 'final'
    hide = 'pavg'
    file_base = 'fsp_steady_low_Re_olshanskii'
  []
[]
(python/peacock/tests/common/fsp_test.i)
[Mesh]
  type = GeneratedMesh
  dim = 2
  nx = 2
  ny = 2
[]
[Variables]
  active = 'u v'
  [./u]
    order = FIRST
    family = LAGRANGE
  [../]
  [./v]
    order = FIRST
    family = LAGRANGE
  [../]
[]
[Kernels]
  active = 'diff_u conv_v diff_v'
  [./diff_u]
    type = Diffusion
    variable = u
  [../]
  [./conv_v]
    type = CoupledForce
    variable = v
    v = u
  [../]
  [./diff_v]
    type = Diffusion
    variable = v
  [../]
[]
[BCs]
  active = 'left_u right_u left_v'
  [./left_u]
    type = DirichletBC
    variable = u
    boundary = 1
    value = 0
  [../]
  [./right_u]
    type = DirichletBC
    variable = u
    boundary = 2
    value = 100
  [../]
  [./left_v]
    type = DirichletBC
    variable = v
    boundary = 1
    value = 0
  [../]
  [./right_v]
    type = DirichletBC
    variable = v
    boundary = 2
    value = 0
  [../]
[]
[Executioner]
  type = Steady
  # This is setup automatically in MOOSE (SetupPBPAction.C)
  # petsc_options = '-snes_mf_operator'
  # petsc_options_iname = '-pc_type'
  # petsc_options_value =  'asm'
[]
[Preconditioning]
  active = 'FSP'
  [./FSP]
    type = FSP
    # It is the starting point of splitting
    topsplit = 'uv' # uv should match the following block name
    [./uv]
      splitting = 'u v' # u and v are the names of subsolvers
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      splitting_type  = additive
      # An approximate solution to the original system
      # | A_uu  A_uv | | u | _ |f_u|
      # |  0    A_vv | | v | - |f_v|
      #  is obtained by solving the following subsystems
      #  A_uu u = f_u and A_vv v = f_v
      # If splitting type is specified as schur, we may also want to set more options to
      # control how schur works using PETSc options
      # petsc_options_iname = '-pc_fieldsplit_schur_fact_type -pc_fieldsplit_schur_precondition'
      # petsc_options_value = 'full selfp'
    [../]
    [./u]
      vars = 'u'
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    [../]
    [./v]
      vars = 'v'
      # PETSc options for this subsolver
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre  preonly'
    [../]
  [../]
[]
[Outputs]
  file_base = out
  exodus = true
[]
(test/tests/preconditioners/fsp/fsp_test.i)
[Mesh]
  [./square]
    type = GeneratedMeshGenerator
    nx = 2
    ny = 2
    dim = 2
  [../]
[]
[Variables]
  active = 'u v'
  [./u]
    order = FIRST
    family = LAGRANGE
  [../]
  [./v]
    order = FIRST
    family = LAGRANGE
  [../]
[]
[Kernels]
  active = 'diff_u conv_v diff_v'
  [./diff_u]
    type = Diffusion
    variable = u
  [../]
  [./conv_v]
    type = CoupledForce
    variable = v
    v = u
  [../]
  [./diff_v]
    type = Diffusion
    variable = v
  [../]
[]
[BCs]
  active = 'left_u right_u left_v'
  [./left_u]
    type = DirichletBC
    variable = u
    boundary = 3
    value = 0
  [../]
  [./right_u]
    type = DirichletBC
    variable = u
    boundary = 1
    value = 100
  [../]
  [./left_v]
    type = DirichletBC
    variable = v
    boundary = 3
    value = 0
  [../]
  [./right_v]
    type = DirichletBC
    variable = v
    boundary = 1
    value = 0
  [../]
[]
[Executioner]
  type = Steady
  # This is setup automatically in MOOSE (SetupPBPAction.C)
  # petsc_options = '-snes_mf_operator'
  # petsc_options_iname = '-pc_type'
  # petsc_options_value =  'asm'
[]
[Preconditioning]
  active = 'FSP'
  [./FSP]
    type = FSP
    # It is the starting point of splitting
    topsplit = 'uv' # 'uv' should match the following block name
    [./uv]
      splitting = 'u v' # 'u' and 'v' are the names of subsolvers
      # Generally speaking, there are four types of splitting we could choose
      # <additive,multiplicative,symmetric_multiplicative,schur>
      splitting_type  = additive
      # An approximate solution to the original system
      # | A_uu  A_uv | | u | _ |f_u|
      # |  0    A_vv | | v | - |f_v|
      #  is obtained by solving the following subsystems
      #  A_uu u = f_u and A_vv v = f_v
      # If splitting type is specified as schur, we may also want to set more options to
      # control how schur works using PETSc options
      # petsc_options_iname = '-pc_fieldsplit_schur_fact_type -pc_fieldsplit_schur_precondition'
      # petsc_options_value = 'full selfp'
    [../]
    [./u]
      vars = 'u'
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     hypre preonly'
    [../]
    [./v]
      vars = 'v'
      # PETSc options for this subsolver
      petsc_options_iname = '-pc_type -ksp_type'
      petsc_options_value = '     lu  preonly'
    [../]
  [../]
[]
[Outputs]
  file_base = out
  exodus = true
[]
(modules/navier_stokes/test/tests/finite_element/ins/pressure_channel/open_bc_pressure_BC_fieldSplit.i)
# This input file tests Dirichlet pressure in/outflow boundary conditions for the incompressible NS equations.
[GlobalParams]
  gravity = '0 0 0'
[]
[Mesh]
  type = GeneratedMesh
  dim = 2
  xmin = 0
  xmax = 3.0
  ymin = 0
  ymax = 1.0
  nx = 30
  ny = 10
  elem_type = QUAD9
[]
[Variables]
  [./vel_x]
    order = SECOND
    family = LAGRANGE
  [../]
  [./vel_y]
    order = SECOND
    family = LAGRANGE
  [../]
  [./p]
    order = FIRST
    family = LAGRANGE
  [../]
[]
[Kernels]
  [./mass]
    type = INSMass
    variable = p
    u = vel_x
    v = vel_y
    pressure = p
  [../]
  [./x_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_x
    u = vel_x
    v = vel_y
    pressure = p
    component = 0
    integrate_p_by_parts = false
  [../]
  [./y_momentum_space]
    type = INSMomentumLaplaceForm
    variable = vel_y
    u = vel_x
    v = vel_y
    pressure = p
    component = 1
    integrate_p_by_parts = false
  [../]
[]
[BCs]
  [./x_no_slip]
    type = DirichletBC
    variable = vel_x
    boundary = 'top bottom'
    value = 0.0
  [../]
  [./y_no_slip]
    type = DirichletBC
    variable = vel_y
    boundary = 'left top bottom'
    value = 0.0
  [../]
  [./inlet_p]
    type = DirichletBC
    variable = p
    boundary = left
    value = 1.0
  [../]
  [./outlet_p]
    type = DirichletBC
    variable = p
    boundary = right
    value = 0.0
  [../]
[]
[Materials]
  [./const]
    type = GenericConstantMaterial
    block = 0
    prop_names = 'rho mu'
    prop_values = '1  1'
  [../]
[]
[Preconditioning]
  active = FSP
  [./FSP]
    type = FSP
    # It is the starting point of splitting
    topsplit = 'up' # 'up' should match the following block name
    [./up]
      splitting = 'u p' # 'u' and 'p' are the names of subsolvers
      splitting_type  = schur
      # Splitting type is set as schur, because the pressure part of Stokes-like systems
      # is not diagonally dominant. CAN NOT use additive, multiplicative and etc.
      # Original system:
      # | A B | | u | = | f_u |
      # | C 0 | | p |   | f_v |
      # is factorized into
      # |I        0 | | A    0|  | I  A^{-1}B | | u | = | f_u |
      # |CA^{-1}  I | | 0   -S|  | 0    I     | | p |   | f_v |
      # S = CA^{-1}B
      # The preconditioning is accomplished via the following steps
      # (1) p^{(0)} = f_v - CA^{-1}f_u,
      # (2) pressure = (-S)^{-1} p^{(0)}
      # (3) u = A^{-1}(f_u-Bp)
      petsc_options_iname = '-pc_fieldsplit_schur_fact_type  -pc_fieldsplit_schur_precondition'
      petsc_options_value = 'full selfp'
      # Factorization type here is full, which means we approximate the original system
      # exactly. There are three other options:
      # diag:
      # | A    0|
      # | 0   -S|
      # lower:
      # |I        0  |
      # |CA^{-1}  -S |
      # upper:
      # | I  A^{-1}B |
      # | 0    -S    |
      # The preconditioning matrix is set as selfp, which means we explicitly form a
      # matrix \hat{S} = C(diag(A))^{-1}B. We do not compute the inverse of A, but instead, we compute
      # the inverse of diag(A).
    [../]
    [./u]
      vars = 'vel_x vel_y'
      # PETSc options for this subsolver
      # A prefix will be applied, so just put the options for this subsolver only
      petsc_options_iname = '-pc_type -ksp_type -ksp_rtol'
      petsc_options_value = '     hypre gmres 1e-4'
      # Specify options to solve A^{-1} in the steps (1), (2) and (3).
      # Solvers for A^{-1} could be different in different steps. We could
      # choose in the following pressure block.
    [../]
    [./p]
      vars = 'p'
      # PETSc options for this subsolver in the step (2)
      petsc_options_iname = '-pc_type -ksp_type -ksp_rtol'
      petsc_options_value = '   jacobi    gmres     1e-4'
      # Use -inner_ksp_type and -inner_pc_type to override A^{-1} in the step (2)
      # Use -lower_ksp_type and -lower_pc_type to override A^{-1} in the step (1)
    [../]
  [../]
[]
[Executioner]
  type = Steady
  solve_type = PJFNK
  nl_rel_tol = 1e-12
  nl_max_its = 6
  l_tol = 1e-6
  l_max_its = 300
[]
[Outputs]
  file_base = open_bc_out_pressure_BC_fieldSplit
  exodus = true
[]