www.mooseframework.org
NormalMortarLMMechanicalContact.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 #include "SubProblem.h"
12 
14 
17  ADMortarConstraint,
18  params.addParam<NonlinearVariableName>("slave_disp_y",
19  "The y displacement variable on the slave face");
20  params.addParam<NonlinearVariableName>("master_disp_y",
21  "The y displacement variable on the master face");
22  MooseEnum ncp_type("min fb", "min");
23  params.addParam<MooseEnum>("ncp_function_type",
24  ncp_type,
25  "The type of the nonlinear complimentarity function; options are "
26  "min or fb where fb stands for Fischer-Burmeister"););
27 
28 template <ComputeStage compute_stage>
30  const InputParameters & parameters)
31  : ADMortarConstraint<compute_stage>(parameters),
32  _slave_disp_y(isParamValid("slave_disp_y") ? &this->_subproblem.getStandardVariable(
33  _tid, parameters.getMooseType("slave_disp_y"))
34  : nullptr),
35  _master_disp_y(
36  isParamValid("master_disp_y")
37  ? &this->_subproblem.getStandardVariable(_tid, parameters.getMooseType("master_disp_y"))
38  : isParamValid("slave_disp_y") ? &this->_subproblem.getStandardVariable(
39  _tid, parameters.getMooseType("slave_disp_y"))
40  : nullptr),
41  _computing_gap_dependence(false),
42  _slave_disp_y_sln(nullptr),
43  _master_disp_y_sln(nullptr),
44  _epsilon(std::numeric_limits<Real>::epsilon()),
45  _ncp_type(getParam<MooseEnum>("ncp_function_type"))
46 {
47  if (_slave_disp_y)
48  {
49  mooseAssert(_master_disp_y,
50  "It doesn't make any sense that we have a slave displacement variable and not a "
51  "master displacement variable");
53  _slave_disp_y_sln = &_slave_disp_y->template adSln<compute_stage>();
54  _master_disp_y_sln = &_master_disp_y->template adSlnNeighbor<compute_stage>();
55  }
56 }
57 
58 template <>
59 Real
61 {
62  switch (mortar_type)
63  {
64  case Moose::MortarType::Lower:
65  {
66  if (_has_master)
67  {
68  auto gap_vec = _phys_points_master[_qp] - _phys_points_slave[_qp];
69  auto gap = gap_vec * _normals[_qp];
70 
71  const auto & a = _lambda[_qp];
72  const auto & b = gap;
73 
74  Real fb_function;
75  if (_ncp_type == "fb")
76  // The FB function (in its pure form) is not differentiable at (0, 0) but if we add some
77  // constant > 0 into the root function, then it is
78  fb_function = a + b - std::sqrt(a * a + b * b + _epsilon);
79  else
80  fb_function = std::min(a, b);
81 
82  return _test[_i][_qp] * fb_function;
83  }
84  else
85  return _test[_i][_qp] * _lambda[_qp];
86  }
87 
88  default:
89  return 0;
90  }
91 }
92 
93 template <>
94 DualReal
96 {
97  switch (mortar_type)
98  {
99  case Moose::MortarType::Lower:
100  {
101  if (_has_master)
102  {
103  DualRealVectorValue gap_vec = _phys_points_master[_qp] - _phys_points_slave[_qp];
104  if (_computing_gap_dependence)
105  {
106  // Here we're assuming that the user provided the x-component as the slave/master
107  // variable!
108  gap_vec(0).derivatives() = _u_master[_qp].derivatives() - _u_slave[_qp].derivatives();
109  gap_vec(1).derivatives() =
110  (*_master_disp_y_sln)[_qp].derivatives() - (*_slave_disp_y_sln)[_qp].derivatives();
111  }
112 
113  auto gap = gap_vec * _normals[_qp];
114 
115  const auto & a = _lambda[_qp];
116  const auto & b = gap;
117 
118  DualReal fb_function;
119  if (_ncp_type == "fb")
120  // The FB function (in its pure form) is not differentiable at (0, 0) but if we add some
121  // constant > 0 into the root function, then it is
122  fb_function = a + b - std::sqrt(a * a + b * b + _epsilon);
123  else
124  fb_function = std::min(a, b);
125 
126  return _test[_i][_qp] * fb_function;
127  }
128  else
129  return _test[_i][_qp] * _lambda[_qp];
130  }
131 
132  default:
133  return 0;
134  }
135 }
NormalMortarLMMechanicalContact::_slave_disp_y
const MooseVariableFE< Real > * _slave_disp_y
Definition: NormalMortarLMMechanicalContact.h:28
NormalMortarLMMechanicalContact::_computing_gap_dependence
bool _computing_gap_dependence
Definition: NormalMortarLMMechanicalContact.h:31
registerADMooseObject
registerADMooseObject("ContactApp", NormalMortarLMMechanicalContact)
NormalMortarLMMechanicalContact::_master_disp_y_sln
const ADVariableValue * _master_disp_y_sln
Definition: NormalMortarLMMechanicalContact.h:34
NormalMortarLMMechanicalContact::computeQpResidual
ADReal computeQpResidual(Moose::MortarType) final
NormalMortarLMMechanicalContact::NormalMortarLMMechanicalContact
NormalMortarLMMechanicalContact(const InputParameters &parameters)
Definition: NormalMortarLMMechanicalContact.C:29
NormalMortarLMMechanicalContact.h
NormalMortarLMMechanicalContact::_master_disp_y
const MooseVariableFE< Real > * _master_disp_y
Definition: NormalMortarLMMechanicalContact.h:29
NormalMortarLMMechanicalContact
Definition: NormalMortarLMMechanicalContact.h:15
defineADValidParams
defineADValidParams(NormalMortarLMMechanicalContact, ADMortarConstraint, params.addParam< NonlinearVariableName >("slave_disp_y", "The y displacement variable on the slave face");params.addParam< NonlinearVariableName >("master_disp_y", "The y displacement variable on the master face");MooseEnum ncp_type("min fb", "min");params.addParam< MooseEnum >("ncp_function_type", ncp_type, "The type of the nonlinear complimentarity function; options are " "min or fb where fb stands for Fischer-Burmeister");)
NormalMortarLMMechanicalContact::_slave_disp_y_sln
const ADVariableValue * _slave_disp_y_sln
Definition: NormalMortarLMMechanicalContact.h:33