This class represents a preliminary implementation of frictional mortar contact constraints intended to be used with Lagrange's multiplier interpolation with dual bases. The nonlinear complementarity constraints employed here are based on a primal-dual active set strategy (PDASS), see (Gitterle et al., 2010). These constraints capture nodes in sticking and slipping states on different solution branches, and can be written as:
is a Lagrange's multiplier that refers to the tangential contact pressure at node , is the weighted tangential velocity integrated forward in time, is the weighted normal gap, is a numerical parameter ( in ComputeWeightedGapLMMechanicalContact
) and is a numerical parameter that can determine convergence properties but has no effect on the results.
The nodal, weighted tangential velocity is computed as
where denotes the secondary contact interface, is the j'th lagrange multiplier test function, and is the discretized version of the tangential velocity function.
This object automatically enforces normal contact constraints by making calls to its parent class ComputeWeightedGapLMMechanicalContact
, see ComputeWeightedGapLMMechanicalContact
for input parameters and details.
The preliminary recommendation is to select c
to be on the order of the moduli of elasticity of the bodies into contact, and c_t
to be a few orders of magnitude less than c
. This selection of these purely numerical parameters can represent an initial difficulty when running new models, but they can be held constant once good convergence behavior has been attained.
Computes the tangential frictional forces
(modules/contact/test/tests/bouncing-block-contact/frictional-nodal-min-normal-lm-mortar-pdass-tangential-lm-mortar-disp.i)
starting_point = 2e-1
# We offset slightly so we avoid the case where the bottom of the secondary block and the top of the
# primary block are perfectly vertically aligned which can cause the backtracking line search some
# issues for a coarse mesh (basic line search handles that fine)
offset = 1e-2
[GlobalParams]
displacements = 'disp_x disp_y'
diffusivity = 1e0
scaling = 1e0
[]
[Mesh]
[file_mesh]
type = FileMeshGenerator
file = long-bottom-block-1elem-blocks-coarse.e
[]
[]
[Variables]
[disp_x]
block = '1 2'
# order = SECOND
[]
[disp_y]
block = '1 2'
# order = SECOND
[]
[frictional_normal_lm]
block = 3
use_dual = true
[]
[frictional_tangential_lm]
block = 3
use_dual = true
[]
[]
[ICs]
[disp_y]
block = 2
variable = disp_y
value = '${fparse starting_point + offset}'
type = ConstantIC
[]
[]
[Kernels]
[disp_x]
type = MatDiffusion
variable = disp_x
[]
[disp_y]
type = MatDiffusion
variable = disp_y
[]
[]
[Constraints]
[frictional_normal_lm]
type = ComputeFrictionalForceLMMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_normal_lm
friction_lm = frictional_tangential_lm
disp_x = disp_x
disp_y = disp_y
mu = 0.1
c = 1.0e-2
c_t = 1.0e-1
[]
[normal_x]
type = NormalMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_normal_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[normal_y]
type = NormalMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_normal_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_x]
type = TangentialMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_tangential_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_y]
type = TangentialMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_tangential_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[]
[BCs]
[botx]
type = DirichletBC
variable = disp_x
boundary = 40
value = 0.0
[]
[boty]
type = DirichletBC
variable = disp_y
boundary = 40
value = 0.0
[]
[topy]
type = FunctionDirichletBC
variable = disp_y
boundary = 30
function = '${starting_point} * cos(2 * pi / 40 * t) + ${offset}'
[]
[leftx]
type = FunctionDirichletBC
variable = disp_x
boundary = 50
function = '1e-2 * t'
[]
[]
[Executioner]
type = Transient
end_time = 200
dt = 5
dtmin = .1
solve_type = 'PJFNK'
petsc_options = '-snes_converged_reason -ksp_converged_reason -pc_svd_monitor '
'-snes_linesearch_monitor -snes_ksp_ew'
petsc_options_iname = '-pc_type -pc_factor_shift_type -pc_factor_shift_amount -mat_mffd_err'
petsc_options_value = 'lu NONZERO 1e-15 1e-5'
l_max_its = 30
nl_max_its = 20
line_search = 'none'
snesmf_reuse_base = false
[]
[Debug]
show_var_residual_norms = true
[]
[Outputs]
exodus = true
[]
[Preconditioning]
[smp]
type = SMP
full = true
[]
[]
[Postprocessors]
[]
(modules/contact/test/tests/pdass_problems/ironing.i)
[GlobalParams]
volumetric_locking_correction = true
displacements = 'disp_x disp_y'
[]
[Mesh]
[input_file]
type = FileMeshGenerator
file = iron.e
[]
[secondary]
type = LowerDBlockFromSidesetGenerator
new_block_id = 10001
new_block_name = 'secondary_lower'
sidesets = '10'
input = input_file
[]
[primary]
type = LowerDBlockFromSidesetGenerator
new_block_id = 10000
sidesets = '20'
new_block_name = 'primary_lower'
input = secondary
[]
patch_update_strategy = auto
patch_size = 20
[]
[Variables]
[disp_x]
[]
[disp_y]
[]
[frictionless_normal_lm]
order = FIRST
family = LAGRANGE
block = 'secondary_lower'
use_dual = true
[]
[tangential_lm]
order = FIRST
family = LAGRANGE
block = 'secondary_lower'
use_dual = true
[]
[]
[AuxVariables]
[stress_xx]
order = CONSTANT
family = MONOMIAL
[]
[stress_yy]
order = CONSTANT
family = MONOMIAL
[]
[stress_xy]
order = CONSTANT
family = MONOMIAL
[]
[saved_x]
[]
[saved_y]
[]
[diag_saved_x]
[]
[diag_saved_y]
[]
[von_mises]
order = CONSTANT
family = MONOMIAL
[]
[]
[Functions]
[disp_ramp_vert]
type = PiecewiseLinear
x = '0. 2. 8.'
y = '0. -1.0 -1.0'
[]
[disp_ramp_horz]
type = PiecewiseLinear
x = '0. 8.' # x = '0. 2. 8.'
y = '0. 8.' # y = '0. 0. 8'
[]
[]
[Kernels]
[TensorMechanics]
use_displaced_mesh = true
save_in = 'saved_x saved_y'
block = '1 2'
strain = FINITE
[]
[]
[AuxKernels]
[stress_xx]
type = RankTwoAux
rank_two_tensor = stress
variable = stress_xx
index_i = 0
index_j = 0
execute_on = timestep_end
block = '1 2'
[]
[stress_yy]
type = RankTwoAux
rank_two_tensor = stress
variable = stress_yy
index_i = 1
index_j = 1
execute_on = timestep_end
block = '1 2'
[]
[stress_xy]
type = RankTwoAux
rank_two_tensor = stress
variable = stress_xy
index_i = 0
index_j = 1
execute_on = timestep_end
block = '1 2'
[]
[von_mises_kernel]
#Calculates the von mises stress and assigns it to von_mises
type = RankTwoScalarAux
variable = von_mises
rank_two_tensor = stress
execute_on = timestep_end
scalar_type = VonMisesStress
block = '1 2'
[]
[]
[Postprocessors]
[bot_react_x]
type = NodalSum
variable = saved_x
boundary = 20
[]
[bot_react_y]
type = NodalSum
variable = saved_y
boundary = 20
[]
[top_react_x]
type = NodalSum
variable = saved_x
boundary = 10
[]
[top_react_y]
type = NodalSum
variable = saved_y
boundary = 10
[]
[_dt]
type = TimestepSize
[]
[contact_pressure]
type = NodalVariableValue
variable = frictionless_normal_lm
nodeid = 805
[]
[]
[BCs]
[bot_x_disp]
type = DirichletBC
variable = disp_x
boundary = '40'
value = 0.0
preset = false
[]
[bot_y_disp]
type = DirichletBC
variable = disp_y
boundary = '40'
value = 0.0
preset = false
[]
[top_y_disp]
type = FunctionDirichletBC
variable = disp_y
boundary = '30'
function = disp_ramp_vert
preset = false
[]
[top_x_disp]
type = FunctionDirichletBC
variable = disp_x
boundary = '30'
function = disp_ramp_horz
preset = false
[]
[]
[Materials]
[stuff1_elas_tens]
type = ComputeIsotropicElasticityTensor
block = '2'
youngs_modulus = 6896
poissons_ratio = 0.32
[]
[stuff1_strain]
type = ComputeFiniteStrain
block = '2'
[]
[stuff1_stress]
type = ComputeFiniteStrainElasticStress
block = '2'
[]
[stuff2_elas_tens]
type = ComputeIsotropicElasticityTensor
block = '1'
youngs_modulus = 689.6
poissons_ratio = 0.32
[]
[stuff2_strain]
type = ComputeFiniteStrain
block = '1'
[]
[stuff2_stress]
type = ComputeFiniteStrainElasticStress
block = '1'
[]
[]
[Executioner]
type = Transient
solve_type = 'PJFNK'
petsc_options_iname = '-pc_type -pc_factor_mat_solver_package'
petsc_options_value = 'lu superlu_dist'
line_search = 'none'
nl_abs_tol = 1e-7
nl_rel_tol = 1e-7
l_tol = 1e-6
l_max_its = 50
nl_max_its = 30
start_time = 0.0
end_time = 0.1 # 6.5
dt = 0.0125
dtmin = 1e-5
[]
[Preconditioning]
[SMP]
type = SMP
full = true
[]
[]
[VectorPostprocessors]
[cont_press]
type = NodalValueSampler
variable = frictionless_normal_lm
boundary = '10'
sort_by = id
execute_on = FINAL
[]
[friction]
type = NodalValueSampler
variable = tangential_lm
boundary = '10'
sort_by = id
execute_on = FINAL
[]
[]
[Outputs]
print_linear_residuals = true
perf_graph = true
exodus = false
csv = true
[chkfile]
type = CSV
show = 'cont_press friction'
start_time = 0.0
execute_vector_postprocessors_on = FINAL
[]
[console]
type = Console
max_rows = 5
[]
[]
[Debug]
show_var_residual_norms = true
[]
[Constraints]
# All constraints below for mechanical contact (Mortar)
[weighted_gap_lm]
type = ComputeFrictionalForceLMMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 10000
secondary_subdomain = 10001
variable = frictionless_normal_lm
disp_x = disp_x
disp_y = disp_y
use_displaced_mesh = true
friction_lm = tangential_lm
mu = 0.5
c_t = 1.0e1
c = 1.0e3
[]
[x]
type = NormalMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = '10000'
secondary_subdomain = '10001'
variable = frictionless_normal_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[y]
type = NormalMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = '10000'
secondary_subdomain = '10001'
variable = frictionless_normal_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_x]
type = TangentialMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = '10000'
secondary_subdomain = '10001'
variable = tangential_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_y]
type = TangentialMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = '10000'
secondary_subdomain = '10001'
variable = tangential_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[]
(modules/contact/test/tests/pdass_problems/frictional_bouncing_block.i)
starting_point = 2e-1
offset = 1e-2
[GlobalParams]
displacements = 'disp_x disp_y'
[]
[Mesh]
file = long-bottom-block-1elem-blocks.e
uniform_refine = 0 # 1,2
patch_update_strategy = always
[]
[Variables]
[disp_x]
block = '1 2'
[]
[disp_y]
block = '1 2'
[]
[frictional_normal_lm]
block = 3
use_dual = true
[]
[frictional_tangential_lm]
block = 3
use_dual = true
[]
[]
[ICs]
[disp_y]
block = 2
variable = disp_y
value = '${fparse starting_point + offset}'
type = ConstantIC
[]
[]
[Modules/TensorMechanics/Master]
[all]
strain = FINITE
generate_output = 'stress_xx stress_yy'
block = '1 2'
[]
[]
[Materials]
[elasticity_2]
type = ComputeIsotropicElasticityTensor
block = '2'
youngs_modulus = 1e3
poissons_ratio = 0.3
[]
[elasticity_1]
type = ComputeIsotropicElasticityTensor
block = '1'
youngs_modulus = 1e6
poissons_ratio = 0.3
[]
[stress]
type = ComputeFiniteStrainElasticStress
block = '1 2'
[]
[]
[Constraints]
[weighted_gap_lm]
type = ComputeFrictionalForceLMMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_normal_lm
disp_x = disp_x
disp_y = disp_y
use_displaced_mesh = true
friction_lm = frictional_tangential_lm
mu = 0.4
c = 1.0e3
c_t = 5.0e1
[]
[normal_x]
type = NormalMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_normal_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[normal_y]
type = NormalMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_normal_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_x]
type = TangentialMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_tangential_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_y]
type = TangentialMortarMechanicalContact
primary_boundary = 20
secondary_boundary = 10
primary_subdomain = 4
secondary_subdomain = 3
variable = frictional_tangential_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[]
[BCs]
[botx]
type = DirichletBC
variable = disp_x
boundary = '40'
value = 0.0
[]
[boty]
type = DirichletBC
variable = disp_y
boundary = '40'
value = 0.0
[]
[topy]
type = ADFunctionDirichletBC
variable = disp_y
boundary = 30
function = '${starting_point} * cos(2 * pi / 20 * t) + ${offset}'
preset = false
[]
[leftx]
type = ADFunctionDirichletBC
variable = disp_x
boundary = 30
function = '2e-2 * t'
# function = '0'
preset = false
[]
[]
[Executioner]
type = Transient
end_time = 7 # 70
dt = 0.25 # 0.1 for finer meshes (uniform_refine)
dtmin = .01
solve_type = 'PJFNK'
petsc_options = '-snes_converged_reason -ksp_converged_reason -pc_svd_monitor '
'-snes_linesearch_monitor '
petsc_options_iname = '-pc_type -pc_factor_shift_type -pc_factor_shift_amount -mat_mffd_err'
petsc_options_value = 'lu NONZERO 1e-15 1e-5'
l_max_its = 30
nl_max_its = 40
line_search = 'none'
snesmf_reuse_base = false
nl_abs_tol = 1e-9
nl_rel_tol = 1e-9
l_tol = 1e-07 # Tightening l_tol can help with friction
[]
[Debug]
show_var_residual_norms = true
[]
[VectorPostprocessors]
[cont_press]
type = NodalValueSampler
variable = frictional_normal_lm
boundary = '10'
sort_by = x
execute_on = FINAL
[]
[friction]
type = NodalValueSampler
variable = frictional_tangential_lm
boundary = '10'
sort_by = x
execute_on = FINAL
[]
[]
[Outputs]
exodus = false
[checkfile]
type = CSV
show = 'cont_press friction'
start_time = 0.0
execute_vector_postprocessors_on = FINAL
[]
[]
[Preconditioning]
[smp]
type = SMP
full = true
[]
[]
[Postprocessors]
active = 'num_nl cumulative_nli contact cumulative_li num_l'
[num_nl]
type = NumNonlinearIterations
[]
[num_l]
type = NumLinearIterations
[]
[cumulative_nli]
type = CumulativeValuePostprocessor
postprocessor = num_nl
[]
[cumulative_li]
type = CumulativeValuePostprocessor
postprocessor = num_l
[]
[contact]
type = ContactDOFSetSize
variable = frictional_normal_lm
subdomain = '3'
execute_on = 'nonlinear timestep_end'
[]
[]
(modules/contact/test/tests/pdass_problems/cylinder_friction.i)
[GlobalParams]
volumetric_locking_correction = true
displacements = 'disp_x disp_y'
[]
[Mesh]
[input_file]
type = FileMeshGenerator
file = hertz_cyl_coarser.e
[]
[secondary]
type = LowerDBlockFromSidesetGenerator
new_block_id = 10001
new_block_name = 'secondary_lower'
sidesets = '3'
input = input_file
[]
[primary]
type = LowerDBlockFromSidesetGenerator
new_block_id = 10000
sidesets = '2'
new_block_name = 'primary_lower'
input = secondary
[]
[]
[Problem]
type = ReferenceResidualProblem
extra_tag_vectors = 'ref'
reference_vector = 'ref'
[]
[Variables]
[disp_x]
[]
[disp_y]
[]
[frictionless_normal_lm]
order = FIRST
family = LAGRANGE
block = 'secondary_lower'
use_dual = true
[]
[tangential_lm]
block = 'secondary_lower'
use_dual = true
[]
[]
[AuxVariables]
[stress_xx]
order = CONSTANT
family = MONOMIAL
[]
[stress_yy]
order = CONSTANT
family = MONOMIAL
[]
[stress_xy]
order = CONSTANT
family = MONOMIAL
[]
[saved_x]
[]
[saved_y]
[]
[diag_saved_x]
[]
[diag_saved_y]
[]
[]
[Functions]
[disp_ramp_vert]
type = PiecewiseLinear
x = '0. 1. 3.5'
y = '0. -0.020 -0.020'
[]
[disp_ramp_horz]
type = PiecewiseLinear
x = '0. 1. 3.5'
y = '0. 0.0 0.015'
[]
[]
[Kernels]
[TensorMechanics]
use_displaced_mesh = true
save_in = 'saved_x saved_y'
extra_vector_tags = 'ref'
block = '1 2 3 4 5 6 7'
[]
[]
[AuxKernels]
[stress_xx]
type = RankTwoAux
rank_two_tensor = stress
variable = stress_xx
index_i = 0
index_j = 0
execute_on = timestep_end
block = '1 2 3 4 5 6 7'
[]
[stress_yy]
type = RankTwoAux
rank_two_tensor = stress
variable = stress_yy
index_i = 1
index_j = 1
execute_on = timestep_end
block = '1 2 3 4 5 6 7'
[]
[stress_xy]
type = RankTwoAux
rank_two_tensor = stress
variable = stress_xy
index_i = 0
index_j = 1
execute_on = timestep_end
block = '1 2 3 4 5 6 7'
[]
[]
[Postprocessors]
[bot_react_x]
type = NodalSum
variable = saved_x
boundary = 1
[]
[bot_react_y]
type = NodalSum
variable = saved_y
boundary = 1
[]
[top_react_x]
type = NodalSum
variable = saved_x
boundary = 4
[]
[top_react_y]
type = NodalSum
variable = saved_y
boundary = 4
[]
[_dt]
type = TimestepSize
[]
[num_lin_it]
type = NumLinearIterations
[]
[num_nonlin_it]
type = NumNonlinearIterations
[]
[]
[BCs]
[side_x]
type = DirichletBC
variable = disp_y
boundary = '1 2'
value = 0.0
[]
[bot_y]
type = DirichletBC
variable = disp_x
boundary = '1 2'
value = 0.0
[]
[top_y_disp]
type = FunctionDirichletBC
variable = disp_y
boundary = 4
function = disp_ramp_vert
[]
[top_x_disp]
type = FunctionDirichletBC
variable = disp_x
boundary = 4
function = disp_ramp_horz
[]
[]
[Materials]
[stuff1_elas_tens]
type = ComputeIsotropicElasticityTensor
block = '1'
youngs_modulus = 1e10
poissons_ratio = 0.0
[]
[stuff1_strain]
type = ComputeFiniteStrain
block = '1'
[]
[stuff1_stress]
type = ComputeFiniteStrainElasticStress
block = '1'
[]
[stuff2_elas_tens]
type = ComputeIsotropicElasticityTensor
block = '2 3 4 5 6 7'
youngs_modulus = 1e6
poissons_ratio = 0.3
[]
[stuff2_strain]
type = ComputeFiniteStrain
block = '2 3 4 5 6 7'
[]
[stuff2_stress]
type = ComputeFiniteStrainElasticStress
block = '2 3 4 5 6 7'
[]
[]
[Executioner]
type = Transient
solve_type = 'PJFNK'
petsc_options_iname = '-pc_type -pc_factor_shift_type -pc_factor_shift_amount -mat_mffd_err'
petsc_options_value = 'lu NONZERO 1e-15 1e-5'
line_search = 'none'
nl_abs_tol = 1e-5
nl_rel_tol = 1e-5
l_max_its = 100
nl_max_its = 30
start_time = 0.0
end_time = 0.3 # 3.5
l_tol = 1e-4
dt = 0.1
dtmin = 0.001
[]
[Preconditioning]
[SMP]
type = SMP
full = true
[]
[]
[VectorPostprocessors]
[x_disp]
type = NodalValueSampler
variable = disp_x
boundary = '3 4'
sort_by = id
[]
[y_disp]
type = NodalValueSampler
variable = disp_y
boundary = '3 4'
sort_by = id
[]
[cont_press]
type = NodalValueSampler
variable = frictionless_normal_lm
boundary = '3'
sort_by = id
[]
[friction]
type = NodalValueSampler
variable = frictionless_normal_lm
boundary = '3'
sort_by = id
[]
[]
[Outputs]
print_linear_residuals = true
perf_graph = true
exodus = true
[console]
type = Console
max_rows = 5
[]
[chkfile]
type = CSV
show = 'x_disp y_disp cont_press friction'
start_time = 0.0
execute_vector_postprocessors_on = FINAL
[]
[]
[Constraints]
[weighted_gap_lm]
type = ComputeFrictionalForceLMMechanicalContact
primary_boundary = 2
secondary_boundary = 3
primary_subdomain = 10000
secondary_subdomain = 10001
variable = frictionless_normal_lm
disp_x = disp_x
disp_y = disp_y
use_displaced_mesh = true
friction_lm = tangential_lm
mu = 0.4
c_t = 1.0e5
c = 1.0e6
[]
[x]
type = NormalMortarMechanicalContact
primary_boundary = '2'
secondary_boundary = '3'
primary_subdomain = '10000'
secondary_subdomain = '10001'
variable = frictionless_normal_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[y]
type = NormalMortarMechanicalContact
primary_boundary = '2'
secondary_boundary = '3'
primary_subdomain = '10000'
secondary_subdomain = '10001'
variable = frictionless_normal_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_x]
type = TangentialMortarMechanicalContact
primary_boundary = 2
secondary_boundary = 3
primary_subdomain = 10000
secondary_subdomain = 10001
variable = tangential_lm
secondary_variable = disp_x
component = x
use_displaced_mesh = true
compute_lm_residuals = false
[]
[tangential_y]
type = TangentialMortarMechanicalContact
primary_boundary = 2
secondary_boundary = 3
primary_subdomain = 10000
secondary_subdomain = 10001
variable = tangential_lm
secondary_variable = disp_y
component = y
use_displaced_mesh = true
compute_lm_residuals = false
[]
[]