www.mooseframework.org
MortarPeriodicAction.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 "MortarPeriodicAction.h"
8 #include "MortarPeriodicMesh.h"
9 #include "Conversion.h"
10 #include "FEProblem.h"
11 #include "Factory.h"
12 
13 #include "libmesh/string_to_enum.h"
14 
15 template <>
16 InputParameters
18 {
19  InputParameters params = validParams<Action>();
20  params.addClassDescription("Add mortar interfaces, Lagrange multiplier variables, and "
21  "constraints to implement mortar based periodicity of values or "
22  "gradients on a MortarPeriodicMesh");
23  params.addParam<std::vector<VariableName>>("variable", "Periodic variables");
24  MooseEnum periodicity_type("gradient value", "gradient");
25  params.addParam<MooseEnum>("periodicity", periodicity_type, "Periodicity type");
26  return params;
27 }
28 
29 MortarPeriodicAction::MortarPeriodicAction(const InputParameters & parameters)
30  : Action(parameters),
31  _variables(getParam<std::vector<VariableName>>("variable")),
32  _periodicity(getParam<MooseEnum>("periodicity"))
33 {
34 }
35 
36 void
38 {
39  // get the mesh
40  MooseSharedPointer<MortarPeriodicMesh> mesh =
41  MooseSharedNamespace::dynamic_pointer_cast<MortarPeriodicMesh>(_mesh);
42  if (!mesh)
43  mooseError("Please use a MortarPeriodicMesh in your simulation.");
44 
45  // mesh dimension
46  const unsigned short dim = mesh->dimension();
47 
48  // periodicity subblock name
49  std::string periodicity_name = name();
50 
51  // axis names
52  const std::vector<BoundaryName> axis = {"x", "y", "z"};
53 
54  // boundaries
55  const std::vector<BoundaryName> boundary_names = {"left", "bottom", "back"};
56  // opposite boundaries
57  const std::vector<BoundaryName> opposite_boundary_names = {"right", "top", "front"};
58 
59  // mortar subdomains
60  const std::vector<SubdomainID> & mortar_subdomains = mesh->getMortarSubdomains();
61 
62  // iterate over the periodic directions
63  for (unsigned short i = 0; i < dim; ++i)
64  if (mesh->getPeriodicDirections().contains(i))
65  {
66  // initialize subdomain restriction set
67  std::set<SubdomainID> subdomain_restriction = {mortar_subdomains[i]};
68 
69  // Lagrange multiplier variable base name
70  const std::string lm_base = "lm_" + periodicity_name + "_" + boundary_names[i];
71 
72  // mortar interface name
73  const std::string mi_name =
74  "mi_" + periodicity_name + "_" + boundary_names[i] + '_' + opposite_boundary_names[i];
75 
76  //
77  // Add Lagrange multiplier variables
78  //
79 
80  if (_current_task == "add_variable")
81  {
82  for (auto & var : _variables)
83  {
84  switch (_periodicity)
85  {
86  case 0: // gradient
87  for (unsigned short j = 0; j < dim; ++j)
88  _problem->addVariable(lm_base + "_" + var + "_d" + axis[j],
89  FEType(Utility::string_to_enum<Order>("FIRST"),
90  Utility::string_to_enum<FEFamily>("LAGRANGE")),
91  1.0,
92  &subdomain_restriction);
93  break;
94 
95  case 1: // value
96  _problem->addVariable(lm_base + "_" + var,
97  FEType(Utility::string_to_enum<Order>("FIRST"),
98  Utility::string_to_enum<FEFamily>("LAGRANGE")),
99  1.0,
100  &subdomain_restriction);
101  break;
102 
103  default:
104  mooseError("Periodicity type not implemented");
105  }
106  }
107  }
108 
109  //
110  // Add Mortar interfaces
111  //
112 
113  if (_current_task == "add_mortar_interface")
114  {
115  _mesh->addMortarInterface(mi_name,
116  boundary_names[i],
117  opposite_boundary_names[i],
118  Moose::stringify(mortar_subdomains[i]));
119  if (_displaced_mesh)
120  _displaced_mesh->addMortarInterface(mi_name,
121  boundary_names[i],
122  opposite_boundary_names[i],
123  Moose::stringify(mortar_subdomains[i]));
124  }
125 
126  //
127  // Add Constraints
128  //
129 
130  if (_current_task == "add_constraint")
131  {
132  for (auto & var : _variables)
133  {
134  const std::string ct_base =
135  "ct_" + periodicity_name + "_" + boundary_names[i] + "_" + var;
136  switch (_periodicity)
137  {
138  case 0: // gradient
139  for (unsigned short j = 0; j < dim; ++j)
140  {
141  InputParameters params = _factory.getValidParams("EqualGradientConstraint");
142  params.set<NonlinearVariableName>("variable") =
143  lm_base + "_" + var + "_d" + axis[j];
144  params.set<VariableName>("master_variable") = var;
145  params.set<std::string>("interface") = mi_name;
146  params.set<unsigned int>("component") = j;
147  _problem->addConstraint(
148  "EqualGradientConstraint", ct_base + "_d" + axis[j], params);
149  }
150  break;
151 
152  case 1: // value
153  {
154  InputParameters params = _factory.getValidParams("EqualValueConstraint");
155  params.set<NonlinearVariableName>("variable") = lm_base + "_" + var;
156  params.set<VariableName>("master_variable") = var;
157  params.set<std::string>("interface") = mi_name;
158  _problem->addConstraint("EqualValueConstraint", ct_base, params);
159  }
160  break;
161 
162  default:
163  mooseError("Periodicity type not implemented");
164  }
165  }
166  }
167  }
168 }
MortarPeriodicAction(const InputParameters &parameters)
std::vector< VariableName > _variables
Mesh generated from parameters with additional subdomains for mortar interfaces to enforce periodicit...
InputParameters validParams< MortarPeriodicAction >()
const unsigned int _periodicity