www.mooseframework.org
Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions | List of all members
ContactAction Class Reference

#include <ContactAction.h>

Inheritance diagram for ContactAction:
[legend]

Public Member Functions

 ContactAction (const InputParameters &params)
 
virtual void act () override
 
virtual void addRelationshipManagers (Moose::RelationshipManagerType input_rm_type) override
 

Static Public Member Functions

static MooseEnum getModelEnum ()
 
static MooseEnum getFormulationEnum ()
 
static MooseEnum getSystemEnum ()
 
static MooseEnum getSmoothingEnum ()
 
static InputParameters commonParameters ()
 

Protected Attributes

const BoundaryName _master
 
const BoundaryName _slave
 
const MooseEnum _model
 
const MooseEnum _formulation
 
const MooseEnum _system
 
const MeshGeneratorName _mesh_gen_name
 

Private Member Functions

void addMortarContact ()
 
void addNodeFaceContact ()
 
void addDiracContact ()
 
std::vector< VariableName > getDisplacementVarNames ()
 

Detailed Description

Definition at line 37 of file ContactAction.h.

Constructor & Destructor Documentation

◆ ContactAction()

ContactAction::ContactAction ( const InputParameters &  params)

Definition at line 92 of file ContactAction.C.

93  : Action(params),
94  _master(getParam<BoundaryName>("master")),
95  _slave(getParam<BoundaryName>("slave")),
96  _model(getParam<MooseEnum>("model")),
97  _formulation(getParam<MooseEnum>("formulation")),
98  _system(getParam<MooseEnum>("system")),
99  _mesh_gen_name(getParam<MeshGeneratorName>("mesh"))
100 {
101 
102  if (_formulation == "tangential_penalty")
103  {
104  if (_system != "Constraint")
105  paramError(
106  "formulation",
107  "The 'tangential_penalty' formulation can only be used with the 'Constraint' system");
108  if (_model != "coulomb")
109  paramError("formulation",
110  "The 'tangential_penalty' formulation can only be used with the 'coulomb' model");
111  }
112 
113  if (_formulation == "mortar")
114  {
115  if (_system != "constraint")
116  paramError("formulation",
117  "The 'mortar' formulation can only be used with the 'Constraint' system");
118  if (_mesh_gen_name.empty())
119  paramError("mesh", "The 'mortar' formulation requires 'mesh' to be supplied");
120  if (_model == "glued")
121  paramError("model", "The 'mortar' formulation does not support glued contact (yet)");
122  }
123 
124  // Make the Dirac kernel deprecated as an initial step for its final removal.
125  MooseEnum makeDiracDeprecated = params.get<MooseEnum>("system");
126  makeDiracDeprecated.deprecate("DiracKernel", "Constraint");
127 
128  if (_system == "DiracKernel")
129  mooseDeprecated(
130  "The DiracKernel-based system for mechanical contact enforcement is deprecated, "
131  "and will be removed on April 1, 2020. It is being replaced by the Constraint-based "
132  "system, which is selected by setting 'system=Constraint'.\n");
133 }

Member Function Documentation

◆ act()

void ContactAction::act ( )
overridevirtual

Definition at line 136 of file ContactAction.C.

137 {
138  if (_formulation == "mortar")
140  else
141  {
142  if (_current_task == "add_dirac_kernel")
143  {
144  // It is risky to apply this optimization to contact problems
145  // since the problem configuration may be changed during Jacobian
146  // evaluation. We therefore turn it off for all contact problems so that
147  // PETSc-3.8.4 or higher will have the same behavior as PETSc-3.8.3.
148  if (!_problem->isSNESMFReuseBaseSetbyUser())
149  _problem->setSNESMFReuseBase(false, false);
150 
151  if (!_problem->getDisplacedProblem())
152  mooseError(
153  "Contact requires updated coordinates. Use the 'displacements = ...' line in the "
154  "Mesh block.");
155 
156  if (_system == "Constraint")
157  // MechanicalContactConstraint has to be added after the init_problem task, so it cannot
158  // be added for the add_constraint task.
160  else if (_system == "DiracKernel")
161  addDiracContact();
162  }
163  }
164 }

◆ addDiracContact()

void ContactAction::addDiracContact ( )
private

Definition at line 374 of file ContactAction.C.

375 {
376  std::string action_name = MooseUtils::shortName(name());
377 
378  std::vector<VariableName> displacements = getDisplacementVarNames();
379  const unsigned int ndisp = displacements.size();
380 
381  {
382  InputParameters params = _factory.getValidParams("ContactMaster");
383  params.applyParameters(parameters(), {"displacements"});
384  params.set<std::vector<VariableName>>("nodal_area") = {"nodal_area_" + name()};
385  params.set<std::vector<VariableName>>("displacements") = displacements;
386  params.set<BoundaryName>("boundary") = _master;
387  params.set<bool>("use_displaced_mesh") = true;
388 
389  for (unsigned int i = 0; i < ndisp; ++i)
390  {
391  std::string name = action_name + "_master_" + Moose::stringify(i);
392  params.set<unsigned int>("component") = i;
393  params.set<NonlinearVariableName>("variable") = displacements[i];
394  _problem->addDiracKernel("ContactMaster", name, params);
395  }
396  }
397 
398  {
399  InputParameters params = _factory.getValidParams("SlaveConstraint");
400  params.applyParameters(parameters(), {"displacements"});
401  params.set<std::vector<VariableName>>("nodal_area") = {"nodal_area_" + name()};
402  params.set<std::vector<VariableName>>("displacements") = displacements;
403  params.set<BoundaryName>("boundary") = _slave;
404  params.set<bool>("use_displaced_mesh") = true;
405 
406  for (unsigned int i = 0; i < ndisp; ++i)
407  {
408  std::string name = action_name + "_slave_" + Moose::stringify(i);
409  params.set<unsigned int>("component") = i;
410  params.set<NonlinearVariableName>("variable") = displacements[i];
411  _problem->addDiracKernel("SlaveConstraint", name, params);
412  }
413  }
414 }

Referenced by act().

◆ addMortarContact()

void ContactAction::addMortarContact ( )
private

Definition at line 174 of file ContactAction.C.

175 {
176  std::string action_name = MooseUtils::shortName(name());
177 
178  std::vector<VariableName> displacements = getDisplacementVarNames();
179  const unsigned int ndisp = displacements.size();
180 
181  // Definitions for mortar contact.
182  const std::string master_subdomain_name = action_name + "_master_subdomain";
183  const std::string slave_subdomain_name = action_name + "_slave_subdomain";
184  const std::string normal_lagrange_multiplier_name = action_name + "_normal_lm";
185  const std::string tangential_lagrange_multiplier_name = action_name + "_tangential_lm";
186 
187  if (_current_task == "add_mesh_generator")
188  {
189  // Don't do mesh generators when recovering.
190  if (!(_app.isRecovering() && _app.isUltimateMaster()) && !_app.masterMesh())
191  {
192  const MeshGeneratorName master_name = master_subdomain_name + "_generator";
193  const MeshGeneratorName slave_name = slave_subdomain_name + "_generator";
194 
195  auto master_params = _factory.getValidParams("LowerDBlockFromSidesetGenerator");
196  auto slave_params = _factory.getValidParams("LowerDBlockFromSidesetGenerator");
197 
198  master_params.set<MeshGeneratorName>("input") = _mesh_gen_name;
199  slave_params.set<MeshGeneratorName>("input") = master_name;
200 
201  master_params.set<SubdomainName>("new_block_name") = master_subdomain_name;
202  slave_params.set<SubdomainName>("new_block_name") = slave_subdomain_name;
203 
204  master_params.set<std::vector<BoundaryName>>("sidesets") = {_master};
205  slave_params.set<std::vector<BoundaryName>>("sidesets") = {_slave};
206 
207  _app.addMeshGenerator("LowerDBlockFromSidesetGenerator", master_name, master_params);
208  _app.addMeshGenerator("LowerDBlockFromSidesetGenerator", slave_name, slave_params);
209  }
210  }
211 
212  if (_current_task == "add_variable")
213  {
214  // Add the lagrange multiplier on the slave subdomain.
215  const auto addLagrangeMultiplier =
216  [this, &slave_subdomain_name, &displacements](const std::string & variable_name,
217  const int codimension) //
218  {
219  InputParameters params = _factory.getValidParams("MooseVariableBase");
220 
221  mooseAssert(_problem->systemBaseNonlinear().hasVariable(displacements[0]),
222  "Displacement variable is missing");
223  const auto primal_type =
224  _problem->systemBaseNonlinear().system().variable_type(displacements[0]);
225  const int lm_order = std::max(primal_type.order.get_order() - codimension, 0);
226 
227  if (primal_type.family == MONOMIAL || (primal_type.family == LAGRANGE && lm_order < 1))
228  {
229  params.set<MooseEnum>("family") = "MONOMIAL";
230  params.set<MooseEnum>("order") = "CONSTANT";
231  }
232  else if (primal_type.family == LAGRANGE)
233  {
234  params.set<MooseEnum>("family") = Utility::enum_to_string<FEFamily>(primal_type.family);
235  params.set<MooseEnum>("order") = Utility::enum_to_string<Order>(OrderWrapper{lm_order});
236  }
237  else
238  mooseError("Primal variable type must be either MONOMIAL or LAGRANGE for mortar contact.");
239 
240  params.set<std::vector<SubdomainName>>("block") = {slave_subdomain_name};
241  auto fe_type = AddVariableAction::feType(params);
242  auto var_type = AddVariableAction::determineType(fe_type, 1);
243  _problem->addVariable(var_type, variable_name, params);
244  };
245 
246  // Set the family/order same as primal for normal contact and one order lower for tangential.
247  addLagrangeMultiplier(normal_lagrange_multiplier_name, 0);
248  if (_model == "coulomb")
249  addLagrangeMultiplier(tangential_lagrange_multiplier_name, 1);
250  }
251 
252  if (_current_task == "add_constraint")
253  {
254  // Add the normal Lagrange multiplier constraint on the slave boundary.
255  {
256  InputParameters params = _factory.getValidParams("NormalNodalLMMechanicalContact");
257 
258  params.set<BoundaryName>("master") = _master;
259  params.set<BoundaryName>("slave") = _slave;
260  params.set<NonlinearVariableName>("variable") = normal_lagrange_multiplier_name;
261  params.set<bool>("use_displaced_mesh") = true;
262  params.set<MooseEnum>("ncp_function_type") = "min";
263  params.set<Real>("c") = getParam<Real>("c_normal");
264 
265  params.set<std::vector<VariableName>>("master_variable") = {displacements[0]};
266  if (ndisp > 1)
267  params.set<std::vector<VariableName>>("disp_y") = {displacements[1]};
268  if (ndisp > 2)
269  params.set<std::vector<VariableName>>("disp_z") = {displacements[2]};
270 
271  _problem->addConstraint("NormalNodalLMMechanicalContact", action_name + "_normal_lm", params);
272  }
273 
274  // Add the tangential Lagrange multiplier constraint on the slave boundary.
275  if (_model == "coulomb")
276  {
277  InputParameters params =
278  _factory.getValidParams("TangentialMortarLMMechanicalContact<RESIDUAL>");
279 
280  params.set<BoundaryName>("master_boundary") = _master;
281  params.set<BoundaryName>("slave_boundary") = _slave;
282  params.set<SubdomainName>("master_subdomain") = master_subdomain_name;
283  params.set<SubdomainName>("slave_subdomain") = slave_subdomain_name;
284  params.set<NonlinearVariableName>("variable") = tangential_lagrange_multiplier_name;
285  params.set<bool>("use_displaced_mesh") = true;
286  params.set<MooseEnum>("ncp_function_type") = "fb";
287  params.set<Real>("c") = getParam<Real>("c_tangential");
288  params.set<bool>("compute_primal_residuals") = false;
289  params.set<NonlinearVariableName>("contact_pressure") = normal_lagrange_multiplier_name;
290  params.set<Real>("friction_coefficient") = getParam<Real>("friction_coefficient");
291 
292  params.set<VariableName>("slave_variable") = displacements[0];
293  if (ndisp > 1)
294  params.set<NonlinearVariableName>("slave_disp_y") = displacements[1];
295  // slave_disp_z is not implemented for tangential (yet).
296 
297  _problem->addConstraint("TangentialMortarLMMechanicalContact<RESIDUAL>",
298  action_name + "_tangential_lm_residual",
299  params);
300  _problem->addConstraint("TangentialMortarLMMechanicalContact<JACOBIAN>",
301  action_name + "_tangential_lm_jacobian",
302  params);
303  }
304 
305  const auto addMechanicalContactConstraints =
306  [this, &master_subdomain_name, &slave_subdomain_name, &displacements](
307  const std::string & variable_name,
308  const std::string & constraint_prefix,
309  const std::string & constraint_type) //
310  {
311  InputParameters params = _factory.getValidParams(constraint_type + "<RESIDUAL>");
312 
313  params.set<BoundaryName>("master_boundary") = _master;
314  params.set<BoundaryName>("slave_boundary") = _slave;
315  params.set<SubdomainName>("master_subdomain") = master_subdomain_name;
316  params.set<SubdomainName>("slave_subdomain") = slave_subdomain_name;
317  params.set<NonlinearVariableName>("variable") = variable_name;
318  params.set<bool>("use_displaced_mesh") = true;
319  params.set<bool>("compute_lm_residuals") = false;
320 
321  for (unsigned int i = 0; i < displacements.size(); ++i)
322  {
323  std::string constraint_name = constraint_prefix + Moose::stringify(i);
324 
325  params.set<VariableName>("slave_variable") = displacements[i];
326  params.set<MooseEnum>("component") = i;
327 
328  _problem->addConstraint(
329  constraint_type + "<RESIDUAL>", constraint_name + "_residual", params);
330  _problem->addConstraint(
331  constraint_type + "<JACOBIAN>", constraint_name + "_jacobian", params);
332  }
333  _problem->haveADObjects(true);
334  };
335 
336  // Add mortar mechanical contact for each dimension
337  addMechanicalContactConstraints(normal_lagrange_multiplier_name,
338  action_name + "_normal_constraint_",
339  "NormalMortarMechanicalContact");
340  if (_model == "coulomb")
341  addMechanicalContactConstraints(tangential_lagrange_multiplier_name,
342  action_name + "_tangential_constraint_",
343  "TangentialMortarMechanicalContact");
344  }
345 }

Referenced by act().

◆ addNodeFaceContact()

void ContactAction::addNodeFaceContact ( )
private

Definition at line 348 of file ContactAction.C.

349 {
350  std::string action_name = MooseUtils::shortName(name());
351 
352  std::vector<VariableName> displacements = getDisplacementVarNames();
353  const unsigned int ndisp = displacements.size();
354 
355  InputParameters params = _factory.getValidParams("MechanicalContactConstraint");
356  params.applyParameters(parameters(), {"displacements"});
357  params.set<std::vector<VariableName>>("nodal_area") = {"nodal_area_" + name()};
358  params.set<std::vector<VariableName>>("displacements") = displacements;
359  params.set<BoundaryName>("boundary") = _master;
360  params.set<bool>("use_displaced_mesh") = true;
361 
362  for (unsigned int i = 0; i < ndisp; ++i)
363  {
364  std::string name = action_name + "_constraint_" + Moose::stringify(i);
365 
366  params.set<unsigned int>("component") = i;
367  params.set<NonlinearVariableName>("variable") = displacements[i];
368  params.set<std::vector<VariableName>>("master_variable") = {displacements[i]};
369  _problem->addConstraint("MechanicalContactConstraint", name, params);
370  }
371 }

Referenced by act().

◆ addRelationshipManagers()

void ContactAction::addRelationshipManagers ( Moose::RelationshipManagerType  input_rm_type)
overridevirtual

Definition at line 167 of file ContactAction.C.

168 {
169  if (_formulation == "mortar")
170  addRelationshipManagers(input_rm_type, _pars);
171 }

◆ commonParameters()

InputParameters ContactAction::commonParameters ( )
static

Definition at line 441 of file ContactAction.C.

442 {
443  InputParameters params = emptyInputParameters();
444 
445  MooseEnum orders(AddVariableAction::getNonlinearVariableOrders());
446  params.addParam<MooseEnum>("order", orders, "The finite element order: FIRST, SECOND, etc.");
447 
448  params.addParam<MooseEnum>("normal_smoothing_method",
450  "Method to use to smooth normals");
451  params.addParam<Real>(
452  "normal_smoothing_distance",
453  "Distance from edge in parametric coordinates over which to smooth contact normal");
454 
455  params.addParam<MooseEnum>(
456  "formulation", ContactAction::getFormulationEnum(), "The contact formulation");
457 
458  params.addParam<MooseEnum>("model", ContactAction::getModelEnum(), "The contact model to use");
459 
460  return params;
461 }

Referenced by validParams< ContactAction >(), validParams< ContactMaster >(), validParams< GluedContactConstraint >(), validParams< MechanicalContactConstraint >(), and validParams< SlaveConstraint >().

◆ getDisplacementVarNames()

std::vector< VariableName > ContactAction::getDisplacementVarNames ( )
private

Definition at line 464 of file ContactAction.C.

465 {
466  std::vector<VariableName> displacements;
467  if (isParamValid("displacements"))
468  displacements = getParam<std::vector<VariableName>>("displacements");
469  else
470  {
471  // Legacy parameter scheme for displacements
472  if (!isParamValid("disp_x"))
473  mooseError("Specify displacement variables using the `displacements` parameter.");
474  displacements.push_back(getParam<VariableName>("disp_x"));
475 
476  if (isParamValid("disp_y"))
477  {
478  displacements.push_back(getParam<VariableName>("disp_y"));
479  if (isParamValid("disp_z"))
480  displacements.push_back(getParam<VariableName>("disp_z"));
481  }
482 
483  mooseDeprecated("use the `displacements` parameter rather than the `disp_*` parameters (those "
484  "will go away with the deprecation of the Solid Mechanics module).");
485  }
486 
487  return displacements;
488 }

Referenced by addDiracContact(), addMortarContact(), and addNodeFaceContact().

◆ getFormulationEnum()

MooseEnum ContactAction::getFormulationEnum ( )
static

Definition at line 423 of file ContactAction.C.

424 {
425  return MooseEnum("kinematic penalty augmented_lagrange tangential_penalty mortar", "kinematic");
426 }

Referenced by commonParameters().

◆ getModelEnum()

MooseEnum ContactAction::getModelEnum ( )
static

Definition at line 417 of file ContactAction.C.

418 {
419  return MooseEnum("frictionless glued coulomb", "frictionless");
420 }

Referenced by commonParameters(), validParams< ContactAction >(), and validParams< MultiDContactConstraint >().

◆ getSmoothingEnum()

MooseEnum ContactAction::getSmoothingEnum ( )
static

Definition at line 435 of file ContactAction.C.

436 {
437  return MooseEnum("edge_based nodal_normal_based", "");
438 }

Referenced by commonParameters().

◆ getSystemEnum()

MooseEnum ContactAction::getSystemEnum ( )
static

Definition at line 429 of file ContactAction.C.

430 {
431  return MooseEnum("DiracKernel Constraint", "DiracKernel");
432 }

Referenced by validParams< ContactAction >().

Member Data Documentation

◆ _formulation

const MooseEnum ContactAction::_formulation
protected

Definition at line 58 of file ContactAction.h.

Referenced by act(), addRelationshipManagers(), and ContactAction().

◆ _master

const BoundaryName ContactAction::_master
protected

Definition at line 55 of file ContactAction.h.

Referenced by addDiracContact(), addMortarContact(), and addNodeFaceContact().

◆ _mesh_gen_name

const MeshGeneratorName ContactAction::_mesh_gen_name
protected

Definition at line 60 of file ContactAction.h.

Referenced by addMortarContact(), and ContactAction().

◆ _model

const MooseEnum ContactAction::_model
protected

Definition at line 57 of file ContactAction.h.

Referenced by addMortarContact(), and ContactAction().

◆ _slave

const BoundaryName ContactAction::_slave
protected

Definition at line 56 of file ContactAction.h.

Referenced by addDiracContact(), and addMortarContact().

◆ _system

const MooseEnum ContactAction::_system
protected

Definition at line 59 of file ContactAction.h.

Referenced by act(), and ContactAction().


The documentation for this class was generated from the following files:
ContactAction::_model
const MooseEnum _model
Definition: ContactAction.h:57
ContactAction::getDisplacementVarNames
std::vector< VariableName > getDisplacementVarNames()
Definition: ContactAction.C:464
ContactAction::_system
const MooseEnum _system
Definition: ContactAction.h:59
ContactAction::addNodeFaceContact
void addNodeFaceContact()
Definition: ContactAction.C:348
ContactAction::_formulation
const MooseEnum _formulation
Definition: ContactAction.h:58
ContactAction::addRelationshipManagers
virtual void addRelationshipManagers(Moose::RelationshipManagerType input_rm_type) override
Definition: ContactAction.C:167
ContactAction::getSmoothingEnum
static MooseEnum getSmoothingEnum()
Definition: ContactAction.C:435
name
const std::string name
Definition: Setup.h:21
ContactAction::getFormulationEnum
static MooseEnum getFormulationEnum()
Definition: ContactAction.C:423
ContactAction::_master
const BoundaryName _master
Definition: ContactAction.h:55
ContactAction::_mesh_gen_name
const MeshGeneratorName _mesh_gen_name
Definition: ContactAction.h:60
ContactAction::_slave
const BoundaryName _slave
Definition: ContactAction.h:56
ContactAction::getModelEnum
static MooseEnum getModelEnum()
Definition: ContactAction.C:417
ContactAction::addMortarContact
void addMortarContact()
Definition: ContactAction.C:174
ContactAction::addDiracContact
void addDiracContact()
Definition: ContactAction.C:374