www.mooseframework.org
ContactAction.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
3 /* */
4 /* All contents are licensed under LGPL V2.1 */
5 /* See LICENSE for full restrictions */
6 /****************************************************************/
7 #include "ContactAction.h"
8 
9 #include "Factory.h"
10 #include "FEProblem.h"
11 #include "Conversion.h"
12 #include "AddVariableAction.h"
13 
14 template <>
15 InputParameters
17 {
18  MooseEnum orders(AddVariableAction::getNonlinearVariableOrders());
19  MooseEnum formulation("DEFAULT KINEMATIC PENALTY AUGMENTED_LAGRANGE TANGENTIAL_PENALTY",
20  "DEFAULT");
21  MooseEnum system("DiracKernel Constraint", "DiracKernel");
22 
23  InputParameters params = validParams<Action>();
24 
25  params.addRequiredParam<BoundaryName>("master", "The master surface");
26  params.addRequiredParam<BoundaryName>("slave", "The slave surface");
27 
28  params.addParam<NonlinearVariableName>("disp_x", "The x displacement");
29  params.addParam<NonlinearVariableName>("disp_y", "The y displacement");
30  params.addParam<NonlinearVariableName>("disp_z", "The z displacement");
31 
32  params.addParam<std::vector<NonlinearVariableName>>(
33  "displacements",
34  "The displacements appropriate for the simulation geometry and coordinate system");
35 
36  params.addParam<Real>(
37  "penalty",
38  1e8,
39  "The penalty to apply. This can vary depending on the stiffness of your materials");
40  params.addParam<Real>("friction_coefficient", 0, "The friction coefficient");
41  params.addParam<Real>("tension_release",
42  0.0,
43  "Tension release threshold. A node in contact "
44  "will not be released if its tensile load is below "
45  "this value. No tension release if negative.");
46  params.addParam<std::string>("model", "frictionless", "The contact model to use");
47  params.addParam<Real>("tangential_tolerance",
48  "Tangential distance to extend edges of contact surfaces");
49  params.addParam<Real>(
50  "capture_tolerance", 0, "Normal distance from surface within which nodes are captured");
51  params.addParam<Real>(
52  "normal_smoothing_distance",
53  "Distance from edge in parametric coordinates over which to smooth contact normal");
54  params.addParam<std::string>("normal_smoothing_method",
55  "Method to use to smooth normals (edge_based|nodal_normal_based)");
56  params.addParam<MooseEnum>("order", orders, "The finite element order: FIRST, SECOND, etc.");
57  params.addParam<MooseEnum>(
58  "formulation",
59  formulation,
60  "The contact formulation: default, penalty, augmented_lagrange, tangential_penalty");
61  params.addParam<MooseEnum>("system",
62  system,
63  "System to use for constraint enforcement. Options are: " +
64  system.getRawNames());
65  params.addParam<bool>("normalize_penalty",
66  false,
67  "Whether to normalize the penalty parameter with the nodal area.");
68  params.addParam<bool>("master_slave_jacobian",
69  true,
70  "Whether to include jacobian entries coupling master and slave nodes.");
71  params.addParam<Real>("al_penetration_tolerance",
72  "The tolerance of the penetration for augmented Lagrangian method.");
73  params.addParam<Real>("al_incremental_slip_tolerance",
74  "The tolerance of the incremental slip for augmented Lagrangian method.");
75 
76  params.addParam<Real>("al_frictional_force_tolerance",
77  "The tolerance of the frictional force for augmented Lagrangian method.");
78  return params;
79 }
80 
81 ContactAction::ContactAction(const InputParameters & params)
82  : Action(params),
83  _master(getParam<BoundaryName>("master")),
84  _slave(getParam<BoundaryName>("slave")),
85  _model(getParam<std::string>("model")),
86  _formulation(getParam<MooseEnum>("formulation")),
87  _system(getParam<MooseEnum>("system"))
88 {
89  if (_formulation == "tangential_penalty")
90  {
91  if (_system != "Constraint")
92  mooseError(
93  "The 'tangential_penalty' formulation can only be used with the 'Constraint' system");
94  if (_model != "coulomb")
95  mooseError("The 'tangential_penalty' formulation can only be used with the 'coulomb' model");
96  }
97 }
98 
99 void
101 {
102  if (!_problem->getDisplacedProblem())
103  mooseError("Contact requires updated coordinates. Use the 'displacements = ...' line in the "
104  "Mesh block.");
105 
106  std::string action_name = MooseUtils::shortName(name());
107 
108  std::vector<NonlinearVariableName> displacements;
109  if (isParamValid("displacements"))
110  displacements = getParam<std::vector<NonlinearVariableName>>("displacements");
111  else
112  {
113  // Legacy parameter scheme for displacements
114  if (!isParamValid("disp_x"))
115  mooseError("Specify displacement variables using the `displacements` parameter.");
116  displacements.push_back(getParam<NonlinearVariableName>("disp_x"));
117 
118  if (isParamValid("disp_y"))
119  {
120  displacements.push_back(getParam<NonlinearVariableName>("disp_y"));
121  if (isParamValid("disp_z"))
122  displacements.push_back(getParam<NonlinearVariableName>("disp_z"));
123  }
124 
125  mooseDeprecated("use the `displacements` parameter rather than the `disp_*` parameters (those "
126  "will go away with the deprecation of the Solid Mechanics module).");
127  }
128 
129  // Determine number of dimensions
130  const unsigned int ndisp = displacements.size();
131 
132  // convert vector of NonlinearVariableName to vector of VariableName
133  std::vector<VariableName> coupled_displacements(ndisp);
134  for (unsigned int i = 0; i < ndisp; ++i)
135  coupled_displacements[i] = displacements[i];
136 
137  if (_current_task == "add_dirac_kernel")
138  {
139  // MechanicalContactConstraint has to be added after the init_problem task, so it cannot be
140  // added for the add_constraint task.
141  if (_system == "Constraint")
142  {
143  InputParameters params = _factory.getValidParams("MechanicalContactConstraint");
144  params.applyParameters(parameters(), {"displacements", "formulation"});
145  params.set<std::string>("formulation") = _formulation;
146  params.set<std::vector<VariableName>>("nodal_area") = {"nodal_area_" + name()};
147  params.set<std::vector<VariableName>>("displacements") = coupled_displacements;
148  params.set<BoundaryName>("boundary") = _master;
149  params.set<bool>("use_displaced_mesh") = true;
150 
151  for (unsigned int i = 0; i < ndisp; ++i)
152  {
153  std::string name = action_name + "_constraint_" + Moose::stringify(i);
154 
155  params.set<unsigned int>("component") = i;
156  params.set<NonlinearVariableName>("variable") = displacements[i];
157  params.set<std::vector<VariableName>>("master_variable") = {coupled_displacements[i]};
158 
159  _problem->addConstraint("MechanicalContactConstraint", name, params);
160  }
161  }
162 
163  if (_system == "DiracKernel")
164  {
165  {
166  InputParameters params = _factory.getValidParams("ContactMaster");
167  params.applyParameters(parameters(), {"displacements", "formulation"});
168  params.set<std::string>("formulation") = _formulation;
169  params.set<std::vector<VariableName>>("nodal_area") = {"nodal_area_" + name()};
170  params.set<std::vector<VariableName>>("displacements") = coupled_displacements;
171  params.set<BoundaryName>("boundary") = _master;
172  params.set<bool>("use_displaced_mesh") = true;
173 
174  for (unsigned int i = 0; i < ndisp; ++i)
175  {
176  std::string name = action_name + "_master_" + Moose::stringify(i);
177  params.set<unsigned int>("component") = i;
178  params.set<NonlinearVariableName>("variable") = displacements[i];
179  _problem->addDiracKernel("ContactMaster", name, params);
180  }
181  }
182 
183  {
184  InputParameters params = _factory.getValidParams("SlaveConstraint");
185  params.applyParameters(parameters(), {"displacements", "formulation"});
186  params.set<std::string>("formulation") = _formulation;
187  params.set<std::vector<VariableName>>("nodal_area") = {"nodal_area_" + name()};
188  params.set<std::vector<VariableName>>("displacements") = coupled_displacements;
189  params.set<BoundaryName>("boundary") = _slave;
190  params.set<bool>("use_displaced_mesh") = true;
191 
192  for (unsigned int i = 0; i < ndisp; ++i)
193  {
194  std::string name = action_name + "_slave_" + Moose::stringify(i);
195  params.set<unsigned int>("component") = i;
196  params.set<NonlinearVariableName>("variable") = displacements[i];
197  _problem->addDiracKernel("SlaveConstraint", name, params);
198  }
199  }
200  }
201  }
202 }
const MooseEnum _system
Definition: ContactAction.h:31
const std::string _formulation
Definition: ContactAction.h:30
virtual void act() override
ContactAction(const InputParameters &params)
Definition: ContactAction.C:81
const BoundaryName _slave
Definition: ContactAction.h:28
const std::string _model
Definition: ContactAction.h:29
InputParameters validParams< ContactAction >()
Definition: ContactAction.C:16
const BoundaryName _master
Definition: ContactAction.h:27