From 808d7ecd858068d3d43570cfbe0f3739c67748b2 Mon Sep 17 00:00:00 2001 From: Benjamin Spencer Date: Wed, 23 Apr 2014 17:57:02 -0600 Subject: [PATCH] Add and test MechanicalContactConstraint ref #2816 MechanicalContactConstraint is a general class for doing the full set of contact formulations and friction models currently supported by the DiracKernel-based mechanical contact system. I've added a few 2D tests of this capability with this commit. We're working on a more comprehensive contact test suite. --- .../blocks_2d/blocks_2d.e | Bin 0 -> 8596 bytes .../blocks_2d/blocks_2d.jou | 16 + .../blocks_2d/frictionless_kinematic.i | 211 +++++++ .../blocks_2d/frictionless_penalty.i | 211 +++++++ .../blocks_2d/glued_kinematic.i | 211 +++++++ .../blocks_2d/glued_penalty.i | 211 +++++++ .../gold/frictionless_kinematic_out.e | Bin 0 -> 102344 bytes .../blocks_2d/gold/frictionless_penalty_out.e | Bin 0 -> 102340 bytes .../blocks_2d/gold/glued_kinematic_out.e | Bin 0 -> 102336 bytes .../blocks_2d/gold/glued_penalty_out.e | Bin 0 -> 102332 bytes .../blocks_2d/tests | 22 + .../include/MechanicalContactConstraint.h | 81 +++ .../contact/src/MechanicalContactConstraint.C | 570 ++++++++++++++++++ modules/contact/src/base/ContactApp.C | 2 + 14 files changed, 1535 insertions(+) create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/blocks_2d.e create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/blocks_2d.jou create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_kinematic.i create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_penalty.i create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_kinematic.i create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_penalty.i create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/frictionless_kinematic_out.e create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/frictionless_penalty_out.e create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/glued_kinematic_out.e create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/glued_penalty_out.e create mode 100644 modules/combined/tests/mechanical_contact_constraint/blocks_2d/tests create mode 100644 modules/contact/include/MechanicalContactConstraint.h create mode 100644 modules/contact/src/MechanicalContactConstraint.C diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/blocks_2d.e b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/blocks_2d.e new file mode 100644 index 0000000000000000000000000000000000000000..4c1ef3848574ede56422d7dda1ea80e672a446d6 GIT binary patch literal 8596 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 literal 0 HcmV?d00001 diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/blocks_2d.jou b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/blocks_2d.jou new file mode 100644 index 000000000000..36b993316d48 --- /dev/null +++ b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/blocks_2d.jou @@ -0,0 +1,16 @@ +brick x 0.6 y 2 z 1 +brick x 0.6 y 0.8 z 1 +volume 2 move {0.6 + 0.01} +volume all move 0 0 -0.5 +surface 1 size 0.15 +surface 7 size 0.1 +mesh surface 1 +mesh surface 7 +sideset 1 curve 3 +sideset 2 curve 1 +sideset 3 curve 15 +sideset 4 curve 13 +block 1 surface 1 +block 2 surface 7 +block all element type QUAD4 +export mesh "blocks_2d.e" overwrite diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_kinematic.i b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_kinematic.i new file mode 100644 index 000000000000..c7dc1d49acc4 --- /dev/null +++ b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_kinematic.i @@ -0,0 +1,211 @@ +[Mesh] + file = blocks_2d.e + displacements = 'disp_x disp_y' +[] + +[Variables] + [./disp_x] + [../] + [./disp_y] + [../] +[] + +[AuxVariables] + [./penetration] + order = FIRST + family = LAGRANGE + [../] + [./nodal_area] + order = FIRST + family = LAGRANGE + [../] + [./inc_slip_x] + [../] + [./inc_slip_y] + [../] + [./accum_slip_x] + [../] + [./accum_slip_y] + [../] +[] + +[Functions] + [./vertical_movement] + type = ParsedFunction + value = -t + [../] +[] + +[SolidMechanics] + [./solid] + disp_x = disp_x + disp_y = disp_y + [../] +[] + +[AuxBCs] + [./penetration] + type = PenetrationAux + variable = penetration + boundary = 3 + paired_boundary = 2 + [../] +[] + +[AuxKernels] + [./zeroslip_x] + type = ConstantAux + variable = inc_slip_x + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./zeroslip_y] + type = ConstantAux + variable = inc_slip_y + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./accum_slip_x] + type = AccumulateAux + variable = accum_slip_x + accumulate_from_variable = inc_slip_x + execute_on = timestep + [../] + [./accum_slip_y] + type = AccumulateAux + variable = accum_slip_y + accumulate_from_variable = inc_slip_y + execute_on = timestep + [../] +[] + +[BCs] + [./left_x] + type = DirichletBC + variable = disp_x + boundary = 1 + value = 0.0 + [../] + [./left_y] + type = DirichletBC + variable = disp_y + boundary = 1 + value = 0.0 + [../] + [./right_x] + type = PresetBC + variable = disp_x + boundary = 4 + #Initial gap is 0.01 + value = -0.02 + [../] + [./right_y] + type = FunctionPresetBC + variable = disp_y + boundary = 4 + function = vertical_movement + [../] +[] + +[Materials] + [./left] + type = LinearIsotropicMaterial + block = 1 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e7 + [../] + [./right] + type = LinearIsotropicMaterial + block = 2 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e6 + [../] +[] + +[Executioner] + type = Transient + + solve_type = 'PJFNK' + + petsc_options_iname = '-pc_type' + petsc_options_value = 'lu' + + line_search = 'none' + + l_max_its = 100 + nl_max_its = 1000 + dt = 0.01 + end_time = 0.10 + num_steps = 1000 + l_tol = 1e-6 + nl_rel_tol = 1e-10 + nl_abs_tol = 1e-8 + dtmin = 0.01 + + [./Predictor] + type = SimplePredictor + scale = 1.0 + [../] +[] + +[Outputs] + file_base = frictionless_kinematic_out + output_initial = true + [./exodus] + type = Exodus + elemental_as_nodal = true + [../] + [./console] + type = Console + perf_log = true + linear_residuals = true + max_rows = 5 + [../] +[] + +[UserObjects] + [./nodal_area] + type = NodalArea + variable = nodal_area + boundary = 3 + execute_on = timestep_begin + use_displaced_mesh = true + [../] +[] + +[Constraints] + [./leftrightx] + type = MechanicalContactConstraint + variable = disp_x + component = 0 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = frictionless + formulation = default + penalty = 1e+6 + nodal_area = nodal_area + [../] + [./leftrighty] + type = MechanicalContactConstraint + variable = disp_y + component = 1 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = frictionless + formulation = default + penalty = 1e+6 + nodal_area = nodal_area + [../] +[] diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_penalty.i b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_penalty.i new file mode 100644 index 000000000000..72efadc41d0c --- /dev/null +++ b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/frictionless_penalty.i @@ -0,0 +1,211 @@ +[Mesh] + file = blocks_2d.e + displacements = 'disp_x disp_y' +[] + +[Variables] + [./disp_x] + [../] + [./disp_y] + [../] +[] + +[AuxVariables] + [./penetration] + order = FIRST + family = LAGRANGE + [../] + [./nodal_area] + order = FIRST + family = LAGRANGE + [../] + [./inc_slip_x] + [../] + [./inc_slip_y] + [../] + [./accum_slip_x] + [../] + [./accum_slip_y] + [../] +[] + +[Functions] + [./vertical_movement] + type = ParsedFunction + value = -t + [../] +[] + +[SolidMechanics] + [./solid] + disp_x = disp_x + disp_y = disp_y + [../] +[] + +[AuxBCs] + [./penetration] + type = PenetrationAux + variable = penetration + boundary = 3 + paired_boundary = 2 + [../] +[] + +[AuxKernels] + [./zeroslip_x] + type = ConstantAux + variable = inc_slip_x + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./zeroslip_y] + type = ConstantAux + variable = inc_slip_y + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./accum_slip_x] + type = AccumulateAux + variable = accum_slip_x + accumulate_from_variable = inc_slip_x + execute_on = timestep + [../] + [./accum_slip_y] + type = AccumulateAux + variable = accum_slip_y + accumulate_from_variable = inc_slip_y + execute_on = timestep + [../] +[] + +[BCs] + [./left_x] + type = DirichletBC + variable = disp_x + boundary = 1 + value = 0.0 + [../] + [./left_y] + type = DirichletBC + variable = disp_y + boundary = 1 + value = 0.0 + [../] + [./right_x] + type = PresetBC + variable = disp_x + boundary = 4 + #Initial gap is 0.01 + value = -0.02 + [../] + [./right_y] + type = FunctionPresetBC + variable = disp_y + boundary = 4 + function = vertical_movement + [../] +[] + +[Materials] + [./left] + type = LinearIsotropicMaterial + block = 1 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e7 + [../] + [./right] + type = LinearIsotropicMaterial + block = 2 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e6 + [../] +[] + +[Executioner] + type = Transient + + solve_type = 'PJFNK' + + petsc_options_iname = '-pc_type' + petsc_options_value = 'lu' + + line_search = 'none' + + l_max_its = 100 + nl_max_its = 1000 + dt = 0.01 + end_time = 0.10 + num_steps = 1000 + l_tol = 1e-6 + nl_rel_tol = 1e-10 + nl_abs_tol = 1e-8 + dtmin = 0.01 + + [./Predictor] + type = SimplePredictor + scale = 1.0 + [../] +[] + +[Outputs] + file_base = frictionless_penalty_out + output_initial = true + [./exodus] + type = Exodus + elemental_as_nodal = true + [../] + [./console] + type = Console + perf_log = true + linear_residuals = true + max_rows = 5 + [../] +[] + +[UserObjects] + [./nodal_area] + type = NodalArea + variable = nodal_area + boundary = 3 + execute_on = timestep_begin + use_displaced_mesh = true + [../] +[] + +[Constraints] + [./leftrightx] + type = MechanicalContactConstraint + variable = disp_x + component = 0 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = frictionless + formulation = penalty + penalty = 1e+7 + nodal_area = nodal_area + [../] + [./leftrighty] + type = MechanicalContactConstraint + variable = disp_y + component = 1 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = frictionless + formulation = penalty + penalty = 1e+7 + nodal_area = nodal_area + [../] +[] diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_kinematic.i b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_kinematic.i new file mode 100644 index 000000000000..77817aa4951e --- /dev/null +++ b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_kinematic.i @@ -0,0 +1,211 @@ +[Mesh] + file = blocks_2d.e + displacements = 'disp_x disp_y' +[] + +[Variables] + [./disp_x] + [../] + [./disp_y] + [../] +[] + +[AuxVariables] + [./penetration] + order = FIRST + family = LAGRANGE + [../] + [./nodal_area] + order = FIRST + family = LAGRANGE + [../] + [./inc_slip_x] + [../] + [./inc_slip_y] + [../] + [./accum_slip_x] + [../] + [./accum_slip_y] + [../] +[] + +[Functions] + [./vertical_movement] + type = ParsedFunction + value = -t + [../] +[] + +[SolidMechanics] + [./solid] + disp_x = disp_x + disp_y = disp_y + [../] +[] + +[AuxBCs] + [./penetration] + type = PenetrationAux + variable = penetration + boundary = 3 + paired_boundary = 2 + [../] +[] + +[AuxKernels] + [./zeroslip_x] + type = ConstantAux + variable = inc_slip_x + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./zeroslip_y] + type = ConstantAux + variable = inc_slip_y + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./accum_slip_x] + type = AccumulateAux + variable = accum_slip_x + accumulate_from_variable = inc_slip_x + execute_on = timestep + [../] + [./accum_slip_y] + type = AccumulateAux + variable = accum_slip_y + accumulate_from_variable = inc_slip_y + execute_on = timestep + [../] +[] + +[BCs] + [./left_x] + type = DirichletBC + variable = disp_x + boundary = 1 + value = 0.0 + [../] + [./left_y] + type = DirichletBC + variable = disp_y + boundary = 1 + value = 0.0 + [../] + [./right_x] + type = PresetBC + variable = disp_x + boundary = 4 + #Initial gap is 0.01 + value = -0.02 + [../] + [./right_y] + type = FunctionPresetBC + variable = disp_y + boundary = 4 + function = vertical_movement + [../] +[] + +[Materials] + [./left] + type = LinearIsotropicMaterial + block = 1 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e7 + [../] + [./right] + type = LinearIsotropicMaterial + block = 2 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e6 + [../] +[] + +[Executioner] + type = Transient + + solve_type = 'PJFNK' + + petsc_options_iname = '-pc_type' + petsc_options_value = 'lu' + + line_search = 'none' + + l_max_its = 100 + nl_max_its = 1000 + dt = 0.01 + end_time = 0.10 + num_steps = 1000 + l_tol = 1e-6 + nl_rel_tol = 1e-10 + nl_abs_tol = 1e-8 + dtmin = 0.01 + + [./Predictor] + type = SimplePredictor + scale = 1.0 + [../] +[] + +[Outputs] + file_base = glued_kinematic_out + output_initial = true + [./exodus] + type = Exodus + elemental_as_nodal = true + [../] + [./console] + type = Console + perf_log = true + linear_residuals = true + max_rows = 5 + [../] +[] + +[UserObjects] + [./nodal_area] + type = NodalArea + variable = nodal_area + boundary = 3 + execute_on = timestep_begin + use_displaced_mesh = true + [../] +[] + +[Constraints] + [./leftrightx] + type = MechanicalContactConstraint + variable = disp_x + component = 0 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = glued + formulation = default + penalty = 1e+6 + nodal_area = nodal_area + [../] + [./leftrighty] + type = MechanicalContactConstraint + variable = disp_y + component = 1 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = glued + formulation = default + penalty = 1e+6 + nodal_area = nodal_area + [../] +[] diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_penalty.i b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_penalty.i new file mode 100644 index 000000000000..cc65c6c36506 --- /dev/null +++ b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/glued_penalty.i @@ -0,0 +1,211 @@ +[Mesh] + file = blocks_2d.e + displacements = 'disp_x disp_y' +[] + +[Variables] + [./disp_x] + [../] + [./disp_y] + [../] +[] + +[AuxVariables] + [./penetration] + order = FIRST + family = LAGRANGE + [../] + [./nodal_area] + order = FIRST + family = LAGRANGE + [../] + [./inc_slip_x] + [../] + [./inc_slip_y] + [../] + [./accum_slip_x] + [../] + [./accum_slip_y] + [../] +[] + +[Functions] + [./vertical_movement] + type = ParsedFunction + value = -t + [../] +[] + +[SolidMechanics] + [./solid] + disp_x = disp_x + disp_y = disp_y + [../] +[] + +[AuxBCs] + [./penetration] + type = PenetrationAux + variable = penetration + boundary = 3 + paired_boundary = 2 + [../] +[] + +[AuxKernels] + [./zeroslip_x] + type = ConstantAux + variable = inc_slip_x + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./zeroslip_y] + type = ConstantAux + variable = inc_slip_y + boundary = 3 + execute_on = timestep_begin + value = 0.0 + [../] + [./accum_slip_x] + type = AccumulateAux + variable = accum_slip_x + accumulate_from_variable = inc_slip_x + execute_on = timestep + [../] + [./accum_slip_y] + type = AccumulateAux + variable = accum_slip_y + accumulate_from_variable = inc_slip_y + execute_on = timestep + [../] +[] + +[BCs] + [./left_x] + type = DirichletBC + variable = disp_x + boundary = 1 + value = 0.0 + [../] + [./left_y] + type = DirichletBC + variable = disp_y + boundary = 1 + value = 0.0 + [../] + [./right_x] + type = PresetBC + variable = disp_x + boundary = 4 + #Initial gap is 0.01 + value = -0.02 + [../] + [./right_y] + type = FunctionPresetBC + variable = disp_y + boundary = 4 + function = vertical_movement + [../] +[] + +[Materials] + [./left] + type = LinearIsotropicMaterial + block = 1 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e7 + [../] + [./right] + type = LinearIsotropicMaterial + block = 2 + disp_y = disp_y + disp_x = disp_x + poissons_ratio = 0.3 + youngs_modulus = 1e6 + [../] +[] + +[Executioner] + type = Transient + + solve_type = 'PJFNK' + + petsc_options_iname = '-pc_type' + petsc_options_value = 'lu' + + line_search = 'none' + + l_max_its = 100 + nl_max_its = 1000 + dt = 0.01 + end_time = 0.10 + num_steps = 1000 + l_tol = 1e-6 + nl_rel_tol = 1e-10 + nl_abs_tol = 1e-8 + dtmin = 0.01 + + [./Predictor] + type = SimplePredictor + scale = 1.0 + [../] +[] + +[Outputs] + file_base = glued_penalty_out + output_initial = true + [./exodus] + type = Exodus + elemental_as_nodal = true + [../] + [./console] + type = Console + perf_log = true + linear_residuals = true + max_rows = 5 + [../] +[] + +[UserObjects] + [./nodal_area] + type = NodalArea + variable = nodal_area + boundary = 3 + execute_on = timestep_begin + use_displaced_mesh = true + [../] +[] + +[Constraints] + [./leftrightx] + type = MechanicalContactConstraint + variable = disp_x + component = 0 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = glued + formulation = penalty + penalty = 1e+7 + nodal_area = nodal_area + [../] + [./leftrighty] + type = MechanicalContactConstraint + variable = disp_y + component = 1 + boundary = 2 + master = 2 + slave = 3 + disp_y = disp_y + disp_x = disp_x + model = glued + formulation = penalty + penalty = 1e+7 + nodal_area = nodal_area + [../] +[] diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/frictionless_kinematic_out.e b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/frictionless_kinematic_out.e new file mode 100644 index 0000000000000000000000000000000000000000..6202de89edde9bf7b06c461a586eedc543bb076d GIT binary patch literal 102344 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 literal 0 HcmV?d00001 diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/frictionless_penalty_out.e b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/frictionless_penalty_out.e new file mode 100644 index 0000000000000000000000000000000000000000..77da9ec5b6d49be809e51d8137fe9ace6bb26254 GIT binary patch literal 102340 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 literal 0 HcmV?d00001 diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/glued_penalty_out.e b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/gold/glued_penalty_out.e new file mode 100644 index 0000000000000000000000000000000000000000..86c3665c376417dab28ce550292be9ed43c123fa GIT binary patch literal 102332 zcmeFa2Ur!!wl)l?2&jMrm7ru0kep+aGe{N?Bqv2c1QaolbIw7M1SN?GqA0RZRLmmg zgo2R)44A<9SLp_3Jonr=-*>)e&Yk;rKfZf~uBx@_-K*Q(?AqPBdImI9R8$KP7!a0W z8Q>l0x;Zq&KhPIhR8)Kjbl4Z*ALxyAD}=c|L17_SBG8BWZ}dhTyn~TJ*?zPSbl-^E z3*)8 zy+bK|aSlKHoBh2|9)IvNQpWHP#KXw^7)KtxGEv5H4fYN}F@Nm9>m_}_sv6~*4oRUf#m#u;$P+y5ab?;D#JB6$UiXD zbxTl)7n=Vz{61qos1a}sdLRD)^j`ej@wWBMGkHw30T+_k` z3_t2~i(e3BV4TAogz1eIDL7}e@ztOgdT)=}Ug#*} z;S&oU51*^>`Q`s)Jk%U-oOqrKf5iXeeDJwudP8lfvwj-OaeKNS?Kl58+2Oe}O*cdm z@28}_A`j_wzdO(VcWuw&wv=)4yl`7)gz4?~<92d$0Esr#AOBolRbn&>05vDgh zF7Ho+#|z2nasRAs9BxY)7ta@u%Yrby{eIjUfoUe8QZ5|B#LQEJeWe zGrb`nH9l9PjTgtl^*#;Uep;WF(>^=~u7hd+wEV+<;+ou#ZASL~FcpZOQuY_W^q<(j zw*NC*=9lsQto^U?e{KKkeoBcV7XG3QDEv{R97W1fq|86@Pw$uhrTuh&DT;r3|MWPr zKzaZEDoKp5IAS##zhXv?AOm@bX*s?BzqZGI>G$v3&wiwHg!p&m;~&$AC;nae2(xp< zn)r9+U5()CTMQb+AEi3Q*8D|Ix0~KSZEF(O&>(1}e^>u))&gbVi zp_I6qzr_2Mzb%w_2meXDX+D@K@pe<@e|u*BKjVe}I#0^{)PH%uw*H&(S}FYgW4t@X zcq^ftm*i*UwErAs|4&&8oj>d%iY%BuU8}qO)CkIcip(K?_S;R7rNqzkp!|%y^JBac zf+GJ({PO8|UBQ2dll>3l{`ceTri@cGo%c+>(|P{PPw|(06kvMXpY5jeDg0%e0!ltb zzs`>`FU5axoT5J&NB);_{%l?)zveTYH!1(eFn~Yz;m>^dvmpLVh_A8nwE@1)#Gfni zbv?dTpT0JpzNW?3mdptFnhjrH;cFo_1bpp+uSxLd)MW@92%HF92>4oOIl>AA9t2(l zJ_LRQ0R%w=Ap~Ir5rmZpq6lIL;s~n{BoHJKq!6SL@MR6YM8Tis@TCL348R}h@yB!g zQCkH;6+sO_9RdG6P7{GZ&_d8g&_U2e&_mEiFhDRwFhVd!FhMXyz}F7u2o?yd5iAj` z5Udew5Nr|b5bP1wAUGg6A~+$eMQ}!NL0E_2ir|Lej^KgdiQt8R|J2}v;EUjg;E%8# zVFN+{!bXHZgdhZbR@#IRg0L9@U!#N}gd=Q0*ouJv`m+ro5@9>S4uqWuyAYxfq7h;c zViDpH;t{A3Xb|Qg%%$k_ki>O?eORBa5A4JGbe&As%yhj>*Uog^EJSUwK3zZf?;}{B zuA}Liny#nm+M2Gb=^C4^ujyKwuCwWyo31xpdw32w@9EmZI?fx{AogJ$=go_NeOSkN z^C9q3beuOo0`_4Y=PiJMeOSkN3nE}2)^XlK2-t^poVPFn_F*08ErNi3SjTyu_K0nefapnc~2h`SjTxwP<&YDMUX_mKCI)sr4Xo{*|1nk2)&Kn;~ z*oSqTw=4qoVIAj_F*08t%!hqSjTzeV-owYj_0C`fPJeF z@LZ;kRjlK@@iB{iSjTze;}`p|j`P+)z&@my(v*6~~n5U|e>!3e<^!GxllB56kPVci_T zg5tyaY6MG)59?M4))XJsZ4hiJKCIgz*i(F1UxVO4@!^;_wj+WQMaQw%QhZp)v7ISC ztmD`&6d%@c>~$0$)^TiCiVy2Jwi^QWVI9YIM{q;HF>!1U1W$^NV|!72SjVxwDL$;@ z*gg~=)^TiKiVy2JjvvK`bvFcm1nk2)j=dfM`*2JgdjmoMMaQu>QhZp)u>&bStmD{0 z6d%@c>|lxy>p0FPiVy2JP6)+^bsT#$#fM|!*r5nv6dlJ7r}(grV{f7Ou#RJIrTDOp zV@FVYSjVxqQG8g(u_GxytmD|*DLxz%$KHXklcM9;yC^=ax z2-t^p96J^P`>>8<$01-J)^Y531ni?mph1{}Fc)DS0xiOP1UdwI1O|i!2n!JwAuu8^ zAuuB>Mqoi;MPNf_tPrdbY!GY_>=5h`)*v__I3hS9tVM7} zm_A-yk?w}zj^KgdiQt7mjX;Ai2jO3RKX9M_Q~cj>i*x!v#h<+&f0p;3@%3llW86u2)>E|8Cvjdcn1V>jc*bt`A%rxGr`e;A0&h&rt}` z2r&q;2yqDU?w+3b+w}ndU{`#s|Ks+%1`+?b7kRw=H~+J~KimIk@L%`+*}y;0^S{dg zomHnB{IgNeml^H>uI?e;?*Cs`)BciQ{3QgX-~X5ik%^EDkPQ4kX8_{14H@odbEC+p|657?94GSsd4lAC zBm*P^Bm*P^Bm*P^|G#6Pd&KdctmViKpib*%u@_hfR6fEwj7PS0znQ2B>R?I%HZiT( zD4P~w$+P^(?B)z&i$3nAf3Xx+N{IA)JedGm7t{OhoB4rKr%2%X2UB2hW4tG(W&(&; z1_NEjOkkvL#O;0UJ7`y)8p#lO0>-*S;`2gnLHoVO*y>&SU~o!cpn1~*(DKk2@3|}q z+I5{?&2m>G>&1=Icjp01j;253f*zQsZ_K_{ zNC)Q1u6qAC>UQ@xN#h+4%hv(*!H#QB{G7VKUc0iubFc)c0#!<{ES3bO8qbE)H>H8k zLZPMlAsgfsxqi^)@CtK`DR!1JG-;2M!0^~W)J*c>Hlih=E!`VtIa-Z zbKiQ&qM$Ql=Nx|Bb(!%hWShU!Io)FhS@)){lzcu4*>bon3@Te8dsk5K z!RLXH9sRM!VaX}TPB>W{mnVe$cFXjdRzUU|OY_ng9mrg*y+2Sp3Nk)UP^F#)$c(*z zL-Fb%$Sl{Js_vbH%zeZH^&U6KY*^&aHB|wb&107ay}}^#^u*;4#)^G(xhpe3p5= zA|y*B^^UfrLo#=pgGiwqBrh)6)fXZJDI&r5Jw+@bVbO!jZH*HU-*~k*qig~av@Qi_ z{niHw)#rK6N$g?XpTR$93t-=ciWzi)Y61C4%9aQ`hD#Pj~R|t`E4U z4X$0pve0D#hxRfOEDZ4r$L`w_{2H>|+jO`Iezxe%FY}WLL60{oNxE+dQESG-zpXSQ zxC0)#`7!Dc;_8`QU1@Cuudv!{p5V8HNchwV*AI9(7-IZ{u{ASyNSk!iId=o-n21BIgb!tJ70o-Qi)iZ?pVo~txt%k@pf~V zUnhjZtIpdqj1q#SQVKd}l3+>3yS8t#La?NF_58W#+<=3BV9!{b32}fyWUBal&rQ$6%HbA`GqNE%5mO-3`itgR^ z%@8X^zw52cBt%cN915L`f~X$l^X+~7kgWcuTg`9^QljK--@l#@iR1IdZuX@>!r?s! zEST6KzI-|3rSdNj7YBC9eXAjMb-zDXd?v(DGjoQ?Jw)S3^)7bxfMhdk59&-4NQtZL zZO|`;Bqm3bq){(Oq^7>k6tn>n=m+_irY1o=+xwvkjy{NENZR}2&Pj+lcW6Y1UIn7# zU8!Y1(m>MYRMDO1RzdP<_T?f|Pa(1K(`h0r8xrT!-jtEM0|^^74+jhRL;Rg&TH#Fx zAzov+UbGn?F2dziqvd+QnX%=R5+#7dO9cycP#qkIkQ)Biz7rwUw)1k16Q3C$GOdj~0wKmEYHVmJK>5 z*q5<>C1!&({qNX-q36zUCo?FaS2lnyX~p{1(yG&+m*VE6~xz_qPddV0`h%#6Po4( zgR;-VG5)B-pwyK*C?6~d@(xKGm<}3&WMGlUGUEy0-%qO5$fuc^SbLZ3(Q)Ep4t zWVvWx)D6O18E|(z34{*aiS4Lm0RDsR^k;7<0JpM1{V~5ZV3`}Y;3kbD&@2voTDr2d z`x*D~g?-T{G_Oaq4C|be*L*c`Z-d-pD*hjtVrKT| zs>*4$Hy6*^ypEAH{Q0vst2N*8;`y^S-H}`onw>Lt&g;wcf;Y=%?RJL`PZ+vp>}+S( zQnh!RAZNwCJ*hmBkTdi$p}=nuWOqAE1a)^pcFvt;+h2yE^%5UBdg&A(d!zFvHmfAa zCdM1xLq0%OO9cNb!K08-*t|X@y%VykYNJXR_dxcE5A+vc0J69;0uF3Zhs>*K4@?qb z(K-qX!Trln!=~tN_rbekj>WCkInZA4uOQEt{v48osd9`+LTGrLPFX$f8FCpAtChTEkSDo zNN_p2u>71TT3^9(P%}&%;=h$j`8+O$nA10)>YUYsHhcf$I2yBKR!{)Niba zSQGpmR4#8}HXeEcgrj^7t6c#oY^ym~d2AJE?5&f(6CndKrfV&vstQ4c`^ZiEAZZZQ zns-rZOCrdg&Cn?tm;fFc-ji?FkAT=><1+*K?_sf9Ig^Ix7ZCL8f9b|t0CaJFm$o-; zhZW(U*Ui;F2=v3O?M-%XfJ4i!`)#Zf&_5eC;<%Lp%cMV)=(`^ThKKifukNlz=QW>O zH)s<RmkcOS4l zl2!fWU)236L^&mRfKT)OUCo>3yx%p);;S2>xJmQ2in?v|qp#gpyQ{h(G%7@;4ANle0a|WB@BN*Rc9~=>l_~ zehWP2>Yg~Xdsn!?1O(44iZ#X530W!)zh5PKC@;Z@UG^|HRhW% z>7HobFnkgort{l>{5+9olvscKFj^ONApQC{?d)-$`*^X=?yTCG<2pB~nzOfX{j9BK zaWhu**^Hg@F)Q=f{n`CFZTH1GVE^oXYm<9jTN!8UY?rUrDPP}0?nZO-(Y0G3cl7y;cIUZ4MvvWwC;+ej~$PJ1@u*@Q6HD#R?gh z42F-**MgiyM)YZEw2;$aGxBKFEy(uij{IVZ)=^#fpwxFL6tXnAmslOrfXsCp7)`VQG-6(xI-g(F#&%KExM{EQh4mPr|)A%pgs={l)2t2FO^n z=UPg7J30@!e9N-C4k@2%zh2(|3{o~OJh>xG6_U@6ozXF-M(39#x$e3lNRnK*Gyftw zPw1;F6qX)<#AlW4;^JE%@sU%`lh{X)IC1!3)df#T9J!QJn*ACQZ*6+}=<*Fn>p6bsNcHdf>HQ69ppwbKr%ow@ZT~(l>dCz?|<8f+(|M(GC(pwGC(pwGC(r$ zFE9Y2ygL|~BVT|}6tiq?oB;^dD3y1=>H{&^#S-(?eL?KJ%B?+{JwYs3fGg{1FQ`%P zKDKR(AgFHB^`)bK533i-k28If2mKf2WiK?fV0Go5N)>lgFmzD8#UR8CCJ{!g<5$0f z?y>tX?J5F5KixET^(HCMP@-0R+;S6Cinb^`uJZ?J?d`Rv6=Z?)vQ}@$EfLompO zq;x;+(hy!HW2ZTy@}kts=oCR6#mf0!V-7LzScBq|#nc2FOOv2vZWY10-;0fX)pvrQ zF`ql*G#kNpaVY+FB{lH*Fa3IxpC80qFCN;e%mBj7#`_Y|*MsbFUbaEL#h}`wy>RV2 zXHcJHl6N4`_qVJWWf`H2AUo%J$eH_LAV_mxhx=hLFc6HIxAiY;J_;MYSiZcPpw7B$ zV;HGJF!^ry`h<2P!P6k(>eQJ5EKy(Am}svC;Y~>#+UHtenMuJ8Ms8!^cRS-h!Vm*1 zo$|Tby6DmOz>_WaYqdalc<06r>L%c=dMk0kM;llcjqN!b%@g=N;~hPeKPxA^~QlbP=)XVy{NV`h47Isp0em8dvr zZD;o9`g}3n6B#>eOUoNZ$NA3M>|yUL2Rdf#oUfN0>cZP*?eo5$MubymZHsKN*gYyU zcIGRu=j=Y{`^?vSDwpn%fV@Xd)CYABLJmEjc3@Z^WH)Hb-)?)0?nBWRb!u!1vYl4n zx^3DES)Vn#Hy^TcC;dY$Kx5^^=&Z{cIeF5N}9a)}+}(fWOwkRF7rFd_R8(M^y= zV-i?F{Ti*Km~-fjULR!Y21hu)Tm~72i#<}f%pvt&Ymn}vYDgHre)!(*ZpbVsjXAne z0CGa&rZ!z0g>-+*x3{&ILRy2ndDWHu&|A)K};5S)@T``}JrcnP-svEqh1Uhoz7lX)L)V-wcvPL`?2BR727U zrNRU5I*_zLH%WTH6B5qQCfBQ~px>|O3Ochlpx>F_{>)2&2(R(D3rrQs)p*&NtRii5CSO*5s3qPrLvHmxEG!T1G%^>-r7H z)`fvwXZqzNc|lMzsyomyxd3D(-!@sseFKF_cJGIeo`Ou!)P!L2dQiAB(&2lk9%Q^( z-<%wb0>X3u0!b4gAPBp2k{LdrC3Z(>r1T(Y*-z{~abY!RK$ri9{4h{v*}6|humxn@ zwHF8P+5xMmS4JN_pbNs0EL_*66hN>pblo*?7Z9QyJ4mPj2zB(u=J6~C;p8Fx$(Sk- zxvZ_$NhE{Jwy-yE52}Kk*(u#eX5Jtx)SFcBn9)?s~UG5(34vVkQ8+`WK40MsURU5tr03CDT;OdYjSR|#+n8SSs7K_uHy>ToCR@Hg& z-ld7K?1s|ewLjFf#`$BQTyA$+dTu}6V_gD|Q?@LkK_tiNudQe17_~>~&fdP0agx?JPTTPlwmSlir;6K6uQST-U^M}FeiHmNGO&6F93)b*Bii4@m{PNz* zgP@l+NWZS_66glJ67DI;1C`(h?liFyAQ>rqNWSn4@XTjF^K$PkV);pCwqxGK1bc5= z*xhUM2-b|6qRZEP2=4oV{0}b}6HAw}-nh1&k>K!(jkSn+Lhx0$tr|BNCioP?kK~VU zBvw6Fw{%``n^<+*wI_6i2duQyx%r{D8{{seY-_eJ1qn5|j-vUcpwu7BXk$?fS`Hqi ztlO$V>kva0$1zq=Rp*?%^4ltqn%AFxlraWa&gi8awoo8woh(boI1&i92a4-fR*4eq z#`o(A>)i>icRg>3RW*dzxv8$(CYr!eFVTF)@)$_jMzY8&Mgh;u#U~1nPJ)QML{jK7 zNs!2LX}Nl*7bHgOZ-_^?fylGKg3Qb);J$9pX5A_WbFu_C=e~>89A9m!@u9$gpn0@4 zuYFB2K`Wu;>ZR#OEVTK=cyG@;fMm3Psi6mw$bI_ z6*g#HL?>_Rz*Q>95Q(R4;W~%z!{Ft%?{+KXC56%Z`3neTd zDW=nf-1s+}3OF@484n(EterBJ1&^fzH`^AYKAU4?N zF5Pt=^!++K*q--;{`v=^>&F&={`i`Xe6dSlz$AR|Dw?OB$aX8%T3K|S2zqi!wh`2r zxdfI>tOUhtie8`UghBp^^>BciIw*+Lb*a^Bg2J0E>jUYVKyg_z6Q_6$DC$H98WAOeQ{|`1_(Md1iWZ40wJDM zLh6Dsh;G+-caihiUw)pTT(82ktY&M^`G}quvFFP{lN&8IGyXjfuB`kmMt0V&%$2HY z+%szjXY7lW|1xV^@^Cgk;+wUVPRz-R37@rTk6KGA)y&vcDoHX+jvj%^Pkg^U)OrF{ zODnh!J&=RSLxHyYgomKglfHh_*d$bP=qh+DFNcbQ9tuSGTc{Az?blef5z1|BUwvF- z0A=PmMAFzTC}VFD?BBi<${Ow4^S<4J-JX+6>WgkbY3GA1^9NZ_$}RP6e|89zL`vK* z*r^D`XX={J;Q9j(te-ut}8`7;#l`_%vO5L$;ZRk(6tg4dU9{|wrM+HrGwlM%44FEo zAUF(}nU|?9xLk(hw$p>l${ip%N{Pz*B?BaX3}T{PrVT0d{ak^MbI>}jw_m6_bRc;! zF;bxa5hNG+Gg}w3bHqtEe1%pR~?^sITnP`0jf2?=xdEQ<4Faf&UZ(M13*dO8!&v$+#o~Bm*P^ zBm*P^Bm@6@7y#v+jq+xk3?LUe|J^vZ8ps~IGAA)x6I9d^?sv5mg2D)#^rYDe3LkAx z-8TQRhH5~xNqn!8c%tUBPa%2nA5{pxQ)ge+C{q&x=jDv% zILi{ecgo8*zYHJ*S*(J1wWbK!dv?(UsvW=^lxBYS!6A_6m(aI~a0P)YeA(%o=CF!> zhufDjevon5D`QeN7o@L?f9e~mhLtB$1oDo%!?LBE9J%SV-K{~5b&7}liA7Rha*p0R zK(N$y(3mG{6N}&PF_t!JBG@uDoh{X`5@Of=ePZL)}L|L0*wg)CYfkC^|b&^_t5lh#-nX6X0e8KcV+hFhU1S-Ndp^)h6yTxWdg zK@Vife{(9j=?j^4t`hZ=@{n<_K!s}D0@5C;R+T?}iJqhJeU3?W7DN_&m`E8eg6zaV z+YG68D7f~8$@AJp$S9FNyHx1_q9u;x2Y_M zH`skUx3~zle%Ttxd1yJLbF?{YeN=#40aNaNe^E#oDvXPMEe6RDu-H?*7Lw^Vq$-Jb zL6Tjfmy?rJyT=!8V4Pd!@& zbwAlPi-vNc+U+t*9rrh zoT>^Xmkr>U`RH84O);=pQ@v%tMHyVqeEE9#{ROa|)4|is7zFD+Z9cfe#0jhnB`rQ{ zp8=P0W4~w5R)FP#O;1H)zk}muRpr`9F))`MmTA%E0Ncc3zqzJPVA_4Vg1tu`EZz=h z$VeUnlV}bZvs05`YI5u_U*ZNZqP4R)>%$EuRdn1h9B+WZ^K+MUBF4dF--RO{J|kdo zL|eb+;d?L@h%e+36b4h(wtRo1PB1-a-e)rT5=_q=GOkQV>qRy!vpZCK6ZBnb@3(V( z0_}%aq;*2-fM`8c7wVD%n!7(8XMBGHwC1ILQlDcAT5WOFpYNoAR^yP?la{TZRY~>w z&DSK*rr&VB)@2+t9Q_R&7rX|o9os^fgWiG0x3r-$LuJqq3A_7BjuBKC%NdTfx`G_- z-5lzoDb)9#Y;1L5=p`eLFT#3BR+O8oYN{Y8|tF`y}e4M*Oojvw+=J z@vs@Y?#_$h296iA_K`GaiMy_|c6A6{PWQZ7dlR4GF;n3gyEbBBICY07)KrhnYY|C; znpWlm)>67q<65@i{%rzk=B~|NB;f$n2W#R=;wGSa;|oC!c^jw}DrzcQ^bGbinR2c5 zrH4IB4qELQc?4B!Ql5T4cO0tF!VE)*fy&8{jrS#4p|bQ+594q%RO;{6)K0h$6?g6B zLYCcz3YJfsO<$@)xmxLCLG&DqvRJ3Mz6~}|nsVOOy(AKLXQ$MPMQ?(V11DN;qvNkc zg8O^GwqYo)ZGJfK$^aC7diFs7z5o=-X|rq>e+Pvb4Rz<18bP7?T)zE0-HO=3{dGj=wL(cIyPRWwbki${4+OW+FvSTdI zd}=j<>??sf))G%4W%tffrZjO#v9?;gF(MyQz8G`#D~mxYmv8k~>o!Pb<>8}peg!FG z1J)1Rhan}$#N?^T7^LvKymW{?2g%3dl%IN}{MB_v#v>UZ86X)T86X)T86X)T86X)T z8Tk7!Ky>Da#8gyp6ZN?wXW!hDCOY%f7lOJwx-W&GYqMMdT1R2EsNo_bS~o%a>5Hr! z(OKPccC3|M6Up&i_<=GA_vg$pFa! z$pFa!$-w^}20%0MK-?r_`Ml4jF(pr-gW{Rrq8D$%vTZ1&YqZh5ORhP@Ebe0ov)S9ZV&v< zx=eyl*;KxztV5cR>JQwN`uH^=H@5fw`;cftw9V-OOJxTk&QPcJdE_P`y|(zR$e0Bo zbshbRwo{By(LAZ&Yg9?7toP|W*e(Tfl2oZ~sR2M-2}`WgR{({f9mTJ$Hh}iro$T7u z5n!MWrkbV!p!d=Hs-1HUs8cVXe>l(t0-rr@bOp!}%SL#;!Ns@NACof$cnr1?eAF>ybT z4i3ypry@XZyyj9z$`+8VzF%NBA_}6L5Bh&yQUI(A3y{CRZX`ir^e?R+YToMaU${wQqOg{HrT*W*x)yI*NSB)c4n$-a^rl zQ*<|1oSfO8`>E!)?5}CF_Ij(n1Af-Cw$KvSI=kE%JLmbOxJj>%v$l7Q6*P6t*x6DN z)B^U;XY542n>)WTU4;CNR|{TEm80(=1Kz~V;enhFBc+bp(Q`be?iMOt`UKe-_p|oZ zpzjOCoKl+8_#sPeb9Tj-Q8kH6YDO17%2tuAA?8JM`R%+taY(*3N_?- zyy4Ay=MBXS-%dq%?SxFR*ByaVOpq?nw}-ao5TuDZtY6xf3aRYAoxGoYA?fTJ&3dIx z5F32q;pyuf5PZ4rL2(uXWN_|cn*8DpdDkn3r?Ooj)#$rezwBB_zBBjmE0c6cnz*&+ z)}D4qeD}QiWbbxJ(Eji|dbvNuikVy;WG{g5#)Ns+DU6Wh-t5eE{v#w+6}JjkZid97 zcJBJ}GDvt3)2LaV011lT!&-V9AU<{2{z~Wqh}+*AOT9f7V%r(dpTAcJF+4et8^Gqw zoTN|3v%$)LQ}+dZ9=L8~^Qc7Fek+3X{`%3g+K?ztvm|04u%M#Tk0< z!2Fm{{Ws2wV7Y0>he@lYpj~%qmA1q-&>at*V9PHC?f1dXto!zWwwv$iHJ>Cw*pXX$%)&?_n1>p6r^kn-nSO)PMj7_dLwZp1`Kz6jV-uA0cez~iW{3Q{ z7AF@E20-DPr;9v`vmrlEP2kM(Nyy)|q4blg0^}=YrJnY3fxIS_XEf^oeK~d;QibVars&T>8qL=_o>uf6B1r{xs=1MnCUPjE z#7qiOKlScey5j((rUoaA>U5yz5AFV}`!GOsW_*nad|yt~XW6o!evwUdX17-HMWXvn6v^_i=>u9vk>pfdwt?uZ z+JC+^j+W@GGdm)*IRwcG&2QrIM137`d+-M9-)F{TrX&L-1OF)oh}O~g6-TVb{!{VE zxFiE410(|^10(|^1OIy%03C}D7JPimLEU_(PM`Y2x-)d3S$bgA zRrLFK&1c(gP3~F+ro;28vlv%^>4)x~!n-5j@~VB3K`j<+KV0HjlgAEgDwbS1>U|ol zgSrm9$_WRv3p5=U)i}XGoPqI1?g%J-)>n$M?1q)&XExt+)+c0i9E^?UWD&Caj#D*? zxe!L>&vRlAx)R!lIv2HS+$9v&X8Or12ob6Zk(~>)ZxPZCcI~s@t{?-TMI zOk23y(+If~-?>p8U4&)@cfy*l*9pxhK5zPXc|fsCZ|OcZ4bXXG^2+MPWl+f~zb-8^ z3A%+ED^_2w2ji6oniCGUgCUhs)!5u%P%mStwhVIzt`~;%E5m3Bk%qeU-d^_z1+L#N zCax_YpyXV{cszEP8p_Yy9!C2*AU5PX67-rT{ zRHuf})f|W7$5$q{X`uT<{Cxf#!Uo~TA-53{rZik+iK^Z@8LBQNINjITDZ)<0G(vTlx z<#ghR%o;UvLgGI|{2>Q=K7Q&pOtHZxGU!EO4av zl!26UL%xqydVk>a4M-69c9rlz&-1Vk(@IyYf;gKBH}zOy zh?P}qnTUQ4F{_omV^39plfEbnx^aTj+>n(AR(gPgZRwn$1}bo%k++iD<^hgFZ=?WFeX>jiMy(e9cq&)vlKHfI)q`9-;TUa-&eRr;H-y#O^v3@&m#St}d3f*d9 z-be$!eiFmGH5P;8`)_m?-7LT-Cw*MdbRjq#T$uLcvI%$=jJfs}alx7us^&6vY~cEK z&l8*AIbgpjbIU4p-wlVwb!^T9!(f+l=UM-&Z(tW8Ko_sK0&F4|Xhp>~f}LQf(Z+Q6IQ!rjBOZfs^ta5a`V8Z)IdFm z;SN~6i*4e|QU;4!$L)vbn}bOn+o_VNelWT?w!Wv&1&jr6H7eW4fGPE8*w%w(V5WGA zv+j8?n7+<+ZvKw$%Tsa2;z7ktFylEzJ<6#KdV79z5<9X74Bg&%>tA&Rz0vQ7m&bht zJ#pC`n%n1qww7Ja(H>J!ja1g})_D%{B4+2c#Faqikp_+EXeG$C1!m95(gLM=Oy{rJZgI578B zmrdcGS--HWC%=Meb(MQ<;*qr&8)3%`lV+4 z-HhEldTO~uOa(O29(?fTgA_ErbIfN|mxIRcwF>;E3eae_oW;H32sAupOVwPt4;r$K z*Xw`%4h^b>9F!)R!~Q|Lxi%*f*>ouWuv{d*?kkyXPP~>^1ka+5C_N>T=WGO^k1X zI$qP&uI0f{+g>~Qm?r>g_0tw6)eb^UU$B$d4QZ&+ZfNeAItSGcMjvL>e}JmJ>_P=T zJ7JH(smZykipnRP> z?bK0UC^x!Dtv0?33J3Ru=V&g15`7`oWox3Luu%W3gGDr*gu=kna8c6-T)8l+iFQhMMt)Ol_ z3+X!cT%K1aAzgi7k)_))NT=I!{KhItNQ?bqAjJO)QXlzk5enY|sjJP|zu%1ftLu!6 zM>0S%Kr%owKr%owKr%owKr%ow@b_VW=uExJc4?m?QJ)?)Wgd#wNn}dt$GFQ9orP;U z7k=D=)=}K?I_kd_-G9RWoZhu|qO)Fuwqddl$@ezqR@;dB`Z*C@8JGS(GbS@786X+> zPccBW|NQ&$e=0s1mt=rsfMkGVfMkGV;C~MTpzkhMuGfA9wET;X8Z7JvV&6D>%iA*0 ze`d?!;IIj_W1Uaj5NreOBc)}XMI5j?o46ixB@k90u@Ph(WdgTzj(uU=6R;+Xcbhs> z2sk>uV`A*w1vcOG1Eh^kg4t+{k7D9nFz~s>Ep6Ndvi8&ut6KVDg;#CW*<$y$up%oKjrLZe}Fk1G71c>BtUH^PI9kOU-R(7zzha#&37gvln zLE0SuMj;0DT#wJI<%(@hA*sW!it39pBwDR4Z<=g}xQUN4!V5bfs=oef=Xta)!NNA` zPW&ZE)~-8W(IN%O4>lV`tk8la`gsNYpJ~TmjMD>wMU%2Vvdj$7yd(gJIpOsG>)iE#S;qtySM-4Qr3DnY-a& zGOT00xjNr{Ex6P(d0p)4Mdt8l49F)JV0% zMY&+Vbt&I#_FG_^<8s%cIv=d6)f4X)v>31gSD+l@fU$!Svi)^kv>j$p0Q{|HLolTKgV z?G5U0d&~3K4ujT4%iiL_9iTO)-EQ#wD`@pgb{!tP3c5k-y?0K0{>#r3lUn)VH)&d7PjhGV{8yJ?kEQ&s%gymnb)DAHfQk*Obi(}i zeHVwydz{|yk2pZ(-9FK-)#gw<+EQL@bQE@1Q^k%B`a^N0(5M=E-bQiuD*&&Foe>t!6mITq zi~vReBY+XW2>d++5G_1g3imx26-Jiwh3{2EwCI`?9Lp_4yLzRyx|s{n(ustYy>p0` zM@U&s^+vQ3i3@RSx6{Y({3>?`QDJd=b+hN+b7AbH7y*pHA0vS3aEfj@&vAe30NBPD z0gM1f03(1AzzF=$5CBcTEv658*g>USVNC7BDNtdp(F{C8|Gt`ySyp;j8B{^Cr`vo7 z5Sgp=+P$VgKW~Qw>n|ecKUl4i+~fo{*CI#xlxD$n#(7SDb_bX(naXC3rGn8#f5*ED z!$5lJ&p*SK3+jGvZ`5f%hdnhyL$Z`-ut; z6u1TQ{$dyQTNeOGN3~gYc9qT%w(y5PsHIuX<4nDGqi_B+Yg5{@@>mOy1rW%f@Sv@a?#G+9!F4H!=5I^W;9n-QXwX=qW%P zYsKjBv@1|{R-&B;={^FImHKXaJ&KQA7;a24gCuX<)jHElkXg&Mj*0#~dpzY!>5EVk zpr)869^Tvul#C*A@e8XVmi15=*W_V{#0l}{)PIHm+${+|8xpcEmCBu=()*Tty6HID zmjTzC)0cimjsexu1)tgY0AkL!wa>X2K-4&m@#lClMB+0UcZ?}Os9Wt)D3=lV-P&y^ zlgfk0schY4k#rx0x3{{vI5(v77Cyem`UIklZA$dXVi3uUYrZi#58>3z_pN;f5V}Ae z+|IHef>oZ(j6R8mi_Hl+`%eymsYR?(g|U! z=gx^c=t9W+Di-#&lMp;QG7-x+1wmJi=6IdyhRdSgyIyuFLf`=fZx8LgU~TBMM~Yen z*83c6XX}rFZt`bec^TLjE`5^|A%G>P-=m;LSFkdiAv29Fg2ji` zO7ow_z(PM}c%6(an0@WQ)lM7%@~_r=Azpf5S}?bi-KPr{y#3yHJk`PUCg>NP?{->K z4tif2xKj;;KtBQW5_Z1<1J3Gg_1hnS0o}{c)>{h(nR`mLlxFC87ox?wqC#Mho|hdV z*$!ISR4cpz8FUQ=6YnpGg4ST-x1D00aOAGpKRLmnpfF| zb}@oXXSvg_hJYz&?Xdwv7aTCm6ci=?aMw*NgTfidu8ptS zq40?L2F9T!C>Z)`JQ$n?d3l_k+Z;LRzKW>>u0jovJ4>qGwIK#_DbiGF?n21jz53pO zuN>qgb7g+dI}6#fF&VtLBFGM$FlULQ`z)f$TJm_#z%|C9EIs=9uCE(CblIB;(#qEE z%66EAwCi6y1e<7(CjZNUS*HO~&n!(@s=R>|!;vl$yA&jQ8E;`Lk%g3Er2va(k`Sve z@Vtj62Qel4_J1eSpLc@A?ec-XKyhW!@D6PNisKr?F~L6id{W$*fl7!y+o0KGYy~mt zTfaR;LJ<9Gn&Md?@Vn~_+Ycjv5x@vw1TX>^0gM1f03(1A__fC0++!89{~%hK$h56WKYd(WHF1#czbL)7 z#j|eB-*aQ^q!DK4McSzaqV_`wJC?aII2s~)?MzR|oHANtGq`~x~5~pkn z5;<3lwz4b>VatHl~TNe zp3>)2cRAhN&L9ySzZ&<(5+o7&NT4Z11c~zsy^`$uhD1I^uF0(2ibQ$bhPEF$kCcC? z(Z-Ehes?7<`xyT7GbF8FYgs5g3+V*4P7wySmGz+_L5+>w%Q~U6VxTv;az*QYPBScT zT-Ncg(ewa&*NSFL+SIWegvax}AhuSN?>es<1UC@sUi*k6%k)z_1Kt!t zvfH*FqR#ZZ{f@r2YSvJQ|A^MJWo-g#r7ELe)HqPm8j1`erXi+lrabWl86pe}A6l^y z!JoG>QMNK3xxapOyN5*%uH0`w{AiCSWHJ9FFjw^hHNBnl_)8IpiS5><{OEzGhYg+V zvYHU_WX5vd%@;y4BK9^C$H8aTUm&7##bzmFoM;cD-2KOCV_obX`z~=pC=?Bs7;QXA}drxf(*sPuzi6q}K=Uen{w$ItB z0><9YM%r*s!FUS{l#5l<^DZRxKeSbXPX42?&)f4s@1wbCq^23@JVTN5?@s_J$XLv< zxDzxLOI%W%et=3tf_t3p9#Cwn;Tf>|2@1#WNlUjlfwC&AT*FLxIAAw zep=r-;N*(VGb{hv%(|k_p4ekNPFT?d9`#n;4*+De0ureFiAo$+e0UdH_m&s(NB;uENbh z)Z%@Bo@XIz$D&o50wn>%kG37khT?`N;a|R#L$N-sY}U>lZj^qYm_^ZLL zkik#YZm0D^=6#+V-MTzTZ`z(HxyS(N6(Vz7t)C!WDJI%crVXwcUVgBu;|-*3N2EF3 zFOVus8S$x}g0uvYX7lt2pr~GKoj%JAv0=s8+|k28-I_k_DWC~d)we44t>Hjb7Te)D zR0>p{YflxAhXdub>_smVeTelVd`Ty6hM4@l3!-_hzq`(`{V)O;0gM1f03(1AzzARj zFaj8XzlQ*#T~<6%?4F7WL)HjCC8;A?*zh`z4k5aa!lKj6fIeoNa_2d~Nblo;Gg38w ok7$*685iw~h*rgHE_7QR6;^nN4Gd`gJvYWqiV?sF{3!ze2glOSvj6}9 literal 0 HcmV?d00001 diff --git a/modules/combined/tests/mechanical_contact_constraint/blocks_2d/tests b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/tests new file mode 100644 index 000000000000..3003d38f7446 --- /dev/null +++ b/modules/combined/tests/mechanical_contact_constraint/blocks_2d/tests @@ -0,0 +1,22 @@ +[Tests] + [./constraint_blocks_2d_frictionless_kinematic] + type = 'Exodiff' + input = 'frictionless_kinematic.i' + exodiff = 'frictionless_kinematic_out.e' + [../] + [./constraint_blocks_2d_frictionless_penalty] + type = 'Exodiff' + input = 'frictionless_penalty.i' + exodiff = 'frictionless_penalty_out.e' + [../] + [./constraint_blocks_2d_glued_kinematic] + type = 'Exodiff' + input = 'glued_kinematic.i' + exodiff = 'glued_kinematic_out.e' + [../] + [./constraint_blocks_2d_glued_penalty] + type = 'Exodiff' + input = 'glued_penalty.i' + exodiff = 'glued_penalty_out.e' + [../] +[] diff --git a/modules/contact/include/MechanicalContactConstraint.h b/modules/contact/include/MechanicalContactConstraint.h new file mode 100644 index 000000000000..0ea8684cf9c4 --- /dev/null +++ b/modules/contact/include/MechanicalContactConstraint.h @@ -0,0 +1,81 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#ifndef MECHANICALCONTACTCONSTRAINT_H +#define MECHANICALCONTACTCONSTRAINT_H + +//MOOSE includes +#include "SparsityBasedContactConstraint.h" + +//ELK includes +#include "ContactMaster.h" + +//Forward Declarations +class MechanicalContactConstraint; + +template<> +InputParameters validParams(); + +/** + * A MechanicalContactConstraint forces the value of a variable to be the same on both sides of an interface. + */ +class MechanicalContactConstraint : + public SparsityBasedContactConstraint +{ +public: + MechanicalContactConstraint(const std::string & name, InputParameters parameters); + virtual ~MechanicalContactConstraint(){} + + virtual void timestepSetup(); + virtual void jacobianSetup(); + + virtual void updateContactSet(bool beginning_of_step = false); + + virtual Real computeQpSlaveValue(); + + virtual Real computeQpResidual(Moose::ConstraintType type); + + virtual Real computeQpJacobian(Moose::ConstraintJacobianType type); + + bool shouldApply(); + void computeContactForce(PenetrationInfo * pinfo); + +protected: + const unsigned int _component; + const ContactModel _model; + const ContactFormulation _formulation; + + const Real _penalty; + const Real _friction_coefficient; + const Real _tension_release; + bool _update_contact_set; + Real _time_last_called; + + NumericVector & _residual_copy; +// std::map _point_to_info; + + unsigned int _x_var; + unsigned int _y_var; + unsigned int _z_var; + + const unsigned int _mesh_dimension; + + RealVectorValue _vars; + + MooseVariable * _nodal_area_var; + SystemBase & _aux_system; + const NumericVector * _aux_solution; +}; + +#endif diff --git a/modules/contact/src/MechanicalContactConstraint.C b/modules/contact/src/MechanicalContactConstraint.C new file mode 100644 index 000000000000..85e3e4dd63c8 --- /dev/null +++ b/modules/contact/src/MechanicalContactConstraint.C @@ -0,0 +1,570 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ +#include "MechanicalContactConstraint.h" + +#include "SystemBase.h" +#include "PenetrationLocator.h" + +// libMesh includes +#include "libmesh/string_to_enum.h" + +template<> +InputParameters validParams() +{ + MooseEnum orders("CONSTANT, FIRST, SECOND, THIRD, FOURTH", "FIRST"); + + InputParameters params = validParams(); + params.addRequiredParam("boundary", "The master boundary"); + params.addRequiredParam("slave", "The slave boundary"); + params.addRequiredParam("component", "An integer corresponding to the direction the variable this kernel acts in. (0 for x, 1 for y, 2 for z)"); + params.addCoupledVar("disp_x", "The x displacement"); + params.addCoupledVar("disp_y", "The y displacement"); + params.addCoupledVar("disp_z", "The z displacement"); + params.addRequiredCoupledVar("nodal_area", "The nodal area"); + params.addParam("model", "frictionless", "The contact model to use"); + + params.set("use_displaced_mesh") = true; + params.addParam("penalty", 1e8, "The penalty to apply. This can vary depending on the stiffness of your materials"); + params.addParam("friction_coefficient", 0, "The friction coefficient"); + params.addParam("tangential_tolerance", "Tangential distance to extend edges of contact surfaces"); + params.addParam("normal_smoothing_distance", "Distance from edge in parametric coordinates over which to smooth contact normal"); + params.addParam("normal_smoothing_method","Method to use to smooth normals (edge_based|nodal_normal_based)"); + params.addParam("order", orders, "The finite element order"); + + params.addParam("tension_release", 0.0, "Tension release threshold. A node in contact will not be released if its tensile load is below this value. Must be positive."); + + params.addParam("formulation", "default", "The contact formulation"); + return params; +} + +MechanicalContactConstraint::MechanicalContactConstraint(const std::string & name, InputParameters parameters) : + SparsityBasedContactConstraint(name, parameters), + _component(getParam("component")), + _model(contactModel(getParam("model"))), + _formulation(contactFormulation(getParam("formulation"))), + _penalty(getParam("penalty")), + _friction_coefficient(getParam("friction_coefficient")), + _tension_release(getParam("tension_release")), + _update_contact_set(true), + _time_last_called(-std::numeric_limits::max()), + _residual_copy(_sys.residualGhosted()), + _x_var(isCoupled("disp_x") ? coupled("disp_x") : 99999), + _y_var(isCoupled("disp_y") ? coupled("disp_y") : 99999), + _z_var(isCoupled("disp_z") ? coupled("disp_z") : 99999), + _mesh_dimension(_mesh.dimension()), + _vars(_x_var, _y_var, _z_var), + _nodal_area_var(getVar("nodal_area", 0)), + _aux_system( _nodal_area_var->sys() ), + _aux_solution( _aux_system.currentSolution() ) +{ + _overwrite_slave_residual = false; + + if (parameters.isParamValid("tangential_tolerance")) + _penetration_locator.setTangentialTolerance(getParam("tangential_tolerance")); + + if (parameters.isParamValid("normal_smoothing_distance")) + _penetration_locator.setNormalSmoothingDistance(getParam("normal_smoothing_distance")); + + if (parameters.isParamValid("normal_smoothing_method")) + _penetration_locator.setNormalSmoothingMethod(parameters.get("normal_smoothing_method")); + + _penetration_locator.setUpdate(false); +} + +void +MechanicalContactConstraint::timestepSetup() +{ + if (_component == 0) + { + _penetration_locator._unlocked_this_step.clear(); + _penetration_locator._locked_this_step.clear(); + bool beginning_of_step = false; + if (_t > _time_last_called) + { + beginning_of_step = true; + _penetration_locator.saveContactStateVars(); + } + updateContactSet(beginning_of_step); + _update_contact_set = false; + _time_last_called = _t; + } +} + +void +MechanicalContactConstraint::jacobianSetup() +{ + if (_component == 0) + { + if (_update_contact_set) + updateContactSet(); + _update_contact_set = true; + } +} + +void +MechanicalContactConstraint::updateContactSet(bool beginning_of_step) +{ + std::set & has_penetrated = _penetration_locator._has_penetrated; + std::map & unlocked_this_step = _penetration_locator._unlocked_this_step; + std::map & locked_this_step = _penetration_locator._locked_this_step; + std::map & lagrange_multiplier = _penetration_locator._lagrange_multiplier; + + std::map::iterator it = _penetration_locator._penetration_info.begin(); + std::map::iterator end = _penetration_locator._penetration_info.end(); + + for (; it!=end; ++it) + { + PenetrationInfo * pinfo = it->second; + if (!pinfo) + continue; + + const unsigned int slave_node_num = it->first; + std::set::iterator hpit = has_penetrated.find(slave_node_num); + + if (beginning_of_step) + { + if (hpit != has_penetrated.end()) + pinfo->_penetrated_at_beginning_of_step = true; + else + pinfo->_penetrated_at_beginning_of_step = false; + + pinfo->_starting_elem = it->second->_elem; + pinfo->_starting_side_num = it->second->_side_num; + pinfo->_starting_closest_point_ref = it->second->_closest_point_ref; + } + + const Node * node = pinfo->_node; + unsigned int dof = node->dof_number(_aux_system.number(), _nodal_area_var->index(), 0); + Real area = (*_aux_solution)( dof ); + if (area == 0) + { + if (_t_step > 1) + mooseError("Zero nodal area found"); + else + area = 1; // Avoid divide by zero during initialization + } + + if (_model == CM_EXPERIMENTAL || + (_model == CM_COULOMB && _formulation == CF_DEFAULT)) + { + + Real resid( -(pinfo->_normal * pinfo->_contact_force) / area ); + + // Moose::out << locked_this_step[slave_node_num] << " " << pinfo->_distance << std::endl; + const Real distance( pinfo->_normal * (pinfo->_closest_point - _mesh.node(node->id()))); + + if (hpit != has_penetrated.end() && resid < -_tension_release && locked_this_step[slave_node_num] < 2) + { + //Moose::out << "Releasing node " << node->id() << " " << resid << " < " << -_tension_release << std::endl; + has_penetrated.erase(hpit); + pinfo->_contact_force.zero(); + pinfo->_mech_status=PenetrationInfo::MS_NO_CONTACT; + ++unlocked_this_step[slave_node_num]; + } + else if (distance > 0) + { + if (hpit == has_penetrated.end()) + { + //Moose::out << "Capturing node " << node->id() << " " << distance << " " << unlocked_this_step[slave_node_num] << std::endl; + ++locked_this_step[slave_node_num]; + has_penetrated.insert(slave_node_num); + } + } + } + else if (_formulation == CF_PENALTY) + { + if (pinfo->_distance >= 0) //Penetrated + { + if (hpit == has_penetrated.end()) + has_penetrated.insert(slave_node_num); + } + else if ((pinfo->_contact_force * pinfo->_normal) / area < 0) //In contact and in compression + { + // Do nothing. + } + else + { + if (hpit != has_penetrated.end()) + has_penetrated.erase(hpit); + pinfo->_contact_force.zero(); + pinfo->_mech_status=PenetrationInfo::MS_NO_CONTACT; + } + } + else + { + if (pinfo->_distance >= 0) + { + if (hpit == has_penetrated.end()) + has_penetrated.insert(slave_node_num); + } + } + + if (_formulation == CF_AUGMENTED_LAGRANGE && hpit != has_penetrated.end()) + { + const RealVectorValue distance_vec(_mesh.node(slave_node_num) - pinfo->_closest_point); + lagrange_multiplier[slave_node_num] += _penalty * pinfo->_normal * distance_vec; + } + } +} + +bool +MechanicalContactConstraint::shouldApply() +{ + //TODO: We'll need to do something to call computeContactForce() for the nodes that are + // off-processor. There are no methods that get called for all nodes (at least + // that I know of), so we can't do this correctly yet, but I'm leaving this here + // to remind us that we need to do this. + +// _point_to_info.clear(); +// +// std::set & has_penetrated = _penetration_locator._has_penetrated; +// +// std::map::iterator it = _penetration_locator._penetration_info.begin(); +// std::map::iterator end = _penetration_locator._penetration_info.end(); +// +// for (; it!=end; ++it) +// { +// PenetrationInfo * pinfo = it->second; +// +// if (!pinfo) +// continue; +// +// unsigned int slave_node_num = it->first; +// +// std::set::iterator hpit = has_penetrated.find(slave_node_num); +// +// if ( hpit != has_penetrated.end() ) +// { +// addPoint(pinfo->_elem, pinfo->_closest_point); +// _point_to_info[pinfo->_closest_point] = pinfo; +// computeContactForce(pinfo); +// } +// } + + std::set::iterator hpit = _penetration_locator._has_penetrated.find(_current_node->id()); + return (hpit != _penetration_locator._has_penetrated.end()); +} + +void +MechanicalContactConstraint::computeContactForce(PenetrationInfo * pinfo) +{ + std::map & lagrange_multiplier = _penetration_locator._lagrange_multiplier; + const Node * node = pinfo->_node; + + RealVectorValue res_vec; + // Build up residual vector + for(unsigned int i=0; i<_mesh_dimension; ++i) + { + long int dof_number = node->dof_number(0, _vars(i), 0); + res_vec(i) = _residual_copy(dof_number); + } + RealVectorValue distance_vec(_mesh.node(node->id()) - pinfo->_closest_point); + RealVectorValue pen_force(_penalty * distance_vec); + RealVectorValue tan_residual(0,0,0); + + switch (_model) + { + case CM_FRICTIONLESS: + case CM_EXPERIMENTAL: + switch (_formulation) + { + case CF_DEFAULT: + pinfo->_contact_force = -pinfo->_normal * (pinfo->_normal * res_vec); + break; + case CF_PENALTY: + pinfo->_contact_force = pinfo->_normal * (pinfo->_normal * pen_force); + break; + case CF_AUGMENTED_LAGRANGE: + pinfo->_contact_force = (pinfo->_normal * (pinfo->_normal * + ( pen_force + lagrange_multiplier[node->id()] * pinfo->_normal))); + //( pen_force + (lagrange_multiplier[node->id()]/distance_vec.size())*distance_vec))); + break; + default: + mooseError("Invalid contact formulation"); + break; + } + pinfo->_mech_status=PenetrationInfo::MS_SLIPPING; + break; + case CM_COULOMB: + switch (_formulation) + { + case CF_DEFAULT: + pinfo->_contact_force = -res_vec; + break; + case CF_PENALTY: + { + distance_vec = pinfo->_incremental_slip + (pinfo->_normal * (_mesh.node(node->id()) - pinfo->_closest_point)) * pinfo->_normal; + pen_force = _penalty * distance_vec; + + // Frictional capacity + // const Real capacity( _friction_coefficient * (pen_force * pinfo->_normal < 0 ? -pen_force * pinfo->_normal : 0) ); + const Real capacity( _friction_coefficient * (res_vec * pinfo->_normal > 0 ? res_vec * pinfo->_normal : 0) ); + + // Elastic predictor + pinfo->_contact_force = pen_force + (pinfo->_contact_force_old - pinfo->_normal*(pinfo->_normal*pinfo->_contact_force_old)); + RealVectorValue contact_force_normal( (pinfo->_contact_force*pinfo->_normal) * pinfo->_normal ); + RealVectorValue contact_force_tangential( pinfo->_contact_force - contact_force_normal ); + + // Tangential magnitude of elastic predictor + const Real tan_mag( contact_force_tangential.size() ); + + if ( tan_mag > capacity ) + { + pinfo->_contact_force = contact_force_normal + capacity * contact_force_tangential / tan_mag; + pinfo->_mech_status=PenetrationInfo::MS_SLIPPING; + } + else + pinfo->_mech_status=PenetrationInfo::MS_STICKING; + break; + } + case CF_AUGMENTED_LAGRANGE: + pinfo->_contact_force = pen_force + + lagrange_multiplier[node->id()]*distance_vec/distance_vec.size(); + break; + default: + mooseError("Invalid contact formulation"); + break; + } + break; + case CM_GLUED: + case CM_TIED: + switch(_formulation) + { + case CF_DEFAULT: + pinfo->_contact_force = -res_vec; + break; + case CF_PENALTY: + pinfo->_contact_force = pen_force; + break; + case CF_AUGMENTED_LAGRANGE: + pinfo->_contact_force = pen_force + + lagrange_multiplier[node->id()]*distance_vec/distance_vec.size(); + break; + default: + mooseError("Invalid contact formulation"); + break; + } + pinfo->_mech_status=PenetrationInfo::MS_STICKING; + break; + default: + mooseError("Invalid or unavailable contact model"); + break; + } +} + +Real +MechanicalContactConstraint::computeQpSlaveValue() +{ + return _u_slave[_qp]; +} + +Real +MechanicalContactConstraint::computeQpResidual(Moose::ConstraintType type) +{ + PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()]; + computeContactForce(pinfo); + Real resid = pinfo->_contact_force(_component); + + switch(type) + { + case Moose::Slave: + if (_formulation == CF_DEFAULT) + { + //Real distance = (*_current_node)(_component) - pinfo->_closest_point(_component); + //Real pen_force = _penalty * distance; + RealVectorValue distance_vec(*_current_node - pinfo->_closest_point); + RealVectorValue pen_force(_penalty * distance_vec); + + if (_model == CM_FRICTIONLESS || _model == CM_EXPERIMENTAL) + resid += pinfo->_normal(_component) * pinfo->_normal * pen_force; + + else if (_model == CM_GLUED || _model == CM_TIED || _model == CM_COULOMB) + resid += pen_force(_component); + + } + return _test_slave[_i][_qp] * resid; + case Moose::Master: + return _test_master[_i][_qp] * -resid; + } + + return 0; +} + +Real +MechanicalContactConstraint::computeQpJacobian(Moose::ConstraintJacobianType type) +{ + PenetrationInfo * pinfo = _penetration_locator._penetration_info[_current_node->id()]; + + switch(type) + { + case Moose::SlaveSlave: + switch(_model) + { + case CM_FRICTIONLESS: + case CM_EXPERIMENTAL: + switch (_formulation) + { + case CF_DEFAULT: + { + double curr_jac = (*_jacobian)( _connected_dof_indices[_j], _current_node->dof_number(0, _vars(_component), 0)); + //TODO: Need off-diagonal terms + return (-curr_jac + _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp]) * pinfo->_normal(_component) * pinfo->_normal(_component); + } + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + //TODO: Need off-diagonal terms + return _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component); + default: + mooseError("Invalid contact formulation"); + } + case CM_COULOMB: + case CM_GLUED: + case CM_TIED: + switch (_formulation) + { + case CF_DEFAULT: + { + double curr_jac = (*_jacobian)( _connected_dof_indices[_j], _current_node->dof_number(0, _vars(_component), 0)); + return -curr_jac + _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp]; + } + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + return _phi_slave[_j][_qp] * _penalty * _test_slave[_i][_qp]; + default: + mooseError("Invalid contact formulation"); + } + default: + mooseError("Invalid or unavailable contact model"); + } + + case Moose::SlaveMaster: + switch(_model) + { + case CM_FRICTIONLESS: + case CM_EXPERIMENTAL: + switch (_formulation) + { + case CF_DEFAULT: + { + Node * curr_master_node = _current_master->get_node(_j); + double curr_jac = (*_jacobian)( curr_master_node->dof_number(0, _vars(_component), 0), _current_node->dof_number(0, _vars(_component), 0)); + //TODO: Need off-diagonal terms + return (-curr_jac - _phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp]) * pinfo->_normal(_component) * pinfo->_normal(_component); + } + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + //TODO: Need off-diagonal terms + return -_phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component); + default: + mooseError("Invalid contact formulation"); + } + case CM_COULOMB: + case CM_GLUED: + case CM_TIED: + switch (_formulation) + { + case CF_DEFAULT: + { + Node * curr_master_node = _current_master->get_node(_j); + double curr_jac = (*_jacobian)( curr_master_node->dof_number(0, _vars(_component), 0), _current_node->dof_number(0, _vars(_component), 0)); + return -curr_jac - _phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp]; + } + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + return -_phi_master[_j][_qp] * _penalty * _test_slave[_i][_qp]; + default: + mooseError("Invalid contact formulation"); + } + default: + mooseError("Invalid or unavailable contact model"); + } + + case Moose::MasterSlave: + switch(_model) + { + case CM_FRICTIONLESS: + case CM_EXPERIMENTAL: + switch (_formulation) + { + case CF_DEFAULT: + { + //TODO: Need off-diagonal terms + double slave_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]); + //TODO: To get off-diagonal terms correct using an approach like this, we would need to assemble in the rows for + //all displacement components times their components of the normal vector. + return slave_jac * _test_master[_i][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component); + } + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + //TODO: Need off-diagonal terms + return -_test_master[_i][_qp] * _penalty * _phi_slave[_j][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component); + default: + mooseError("Invalid contact formulation"); + } + case CM_COULOMB: + case CM_GLUED: + case CM_TIED: + switch (_formulation) + { + case CF_DEFAULT: + { + double slave_jac = (*_jacobian)(_current_node->dof_number(0, _vars(_component), 0), _connected_dof_indices[_j]); + return slave_jac * _test_master[_i][_qp]; + } + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + return -_test_master[_i][_qp] * _penalty * _phi_slave[_j][_qp]; + default: + mooseError("Invalid contact formulation"); + } + default: + mooseError("Invalid or unavailable contact model"); + } + + case Moose::MasterMaster: + switch(_model) + { + case CM_FRICTIONLESS: + case CM_EXPERIMENTAL: + switch (_formulation) + { + case CF_DEFAULT: + return 0; + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + //TODO: Need off-diagonal terms + return _test_master[_i][_qp] * _penalty * _phi_master[_j][_qp] * pinfo->_normal(_component) * pinfo->_normal(_component); + default: + mooseError("Invalid contact formulation"); + } + case CM_COULOMB: + case CM_GLUED: + case CM_TIED: + switch (_formulation) + { + case CF_DEFAULT: + return 0; + case CF_PENALTY: + case CF_AUGMENTED_LAGRANGE: + return _test_master[_i][_qp] * _penalty * _phi_master[_j][_qp]; + default: + mooseError("Invalid contact formulation"); + } + default: + mooseError("Invalid or unavailable contact model"); + } + } + + return 0; +} diff --git a/modules/contact/src/base/ContactApp.C b/modules/contact/src/base/ContactApp.C index 91f52ebca778..e7b12908824a 100644 --- a/modules/contact/src/base/ContactApp.C +++ b/modules/contact/src/base/ContactApp.C @@ -14,6 +14,7 @@ #include "OneDContactConstraint.h" #include "MultiDContactConstraint.h" #include "GluedContactConstraint.h" +#include "MechanicalContactConstraint.h" #include "SparsityBasedContactConstraint.h" #include "FrictionalContactProblem.h" #include "ReferenceResidualProblem.h" @@ -58,6 +59,7 @@ ContactApp::registerObjects(Factory & factory) registerConstraint(OneDContactConstraint); registerConstraint(MultiDContactConstraint); registerConstraint(GluedContactConstraint); + registerConstraint(MechanicalContactConstraint); registerConstraint(SparsityBasedContactConstraint); registerProblem(FrictionalContactProblem); registerProblem(ReferenceResidualProblem);