www.mooseframework.org
XFEMAction.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 
10 #include "XFEMAction.h"
11 
12 // MOOSE includes
13 #include "FEProblem.h"
14 #include "NonlinearSystem.h"
15 #include "Executioner.h"
16 #include "MooseEnum.h"
17 #include "Parser.h"
18 #include "Factory.h"
19 #include "AddVariableAction.h"
20 
21 #include "GeometricCutUserObject.h"
22 #include "CrackFrontDefinition.h"
23 
24 #include "libmesh/transient_system.h"
25 #include "libmesh/string_to_enum.h"
26 
27 // XFEM includes
28 #include "XFEM.h"
29 
30 registerMooseAction("XFEMApp", XFEMAction, "setup_xfem");
31 
32 registerMooseAction("XFEMApp", XFEMAction, "add_aux_variable");
33 
34 registerMooseAction("XFEMApp", XFEMAction, "add_aux_kernel");
35 
36 registerMooseAction("XFEMApp", XFEMAction, "add_variable");
37 
38 registerMooseAction("XFEMApp", XFEMAction, "add_kernel");
39 
40 registerMooseAction("XFEMApp", XFEMAction, "add_bc");
41 
42 template <>
43 InputParameters
45 {
46  InputParameters params = validParams<Action>();
47 
48  params.addParam<std::vector<UserObjectName>>(
49  "geometric_cut_userobjects",
50  "List of names of GeometricCutUserObjects with cut info and methods");
51  params.addParam<std::string>("qrule", "volfrac", "XFEM quadrature rule to use");
52  params.addRangeCheckedParam<unsigned int>(
53  "debug_output_level",
54  1,
55  "debug_output_level <= 3",
56  "Controls the amount of debug output from XFEM. 0: None, 1: Summary, 2: Details on "
57  "modifications to mesh, 3: Full dump of element fragment algorithm mesh");
58  params.addParam<bool>("output_cut_plane", false, "Output the XFEM cut plane and volume fraction");
59  params.addParam<bool>("use_crack_growth_increment", false, "Use fixed crack growth increment");
60  params.addParam<Real>("crack_growth_increment", 0.1, "Crack growth increment");
61  params.addParam<bool>("use_crack_tip_enrichment", false, "Use crack tip enrichment functions");
62  params.addParam<UserObjectName>("crack_front_definition",
63  "The CrackFrontDefinition user object name (only "
64  "needed if 'use_crack_tip_enrichment=true')");
65  params.addParam<std::vector<VariableName>>("displacements",
66  "Names of displacement variables (only "
67  "needed if 'use_crack_tip_enrichment=true')");
68  params.addParam<std::vector<VariableName>>("enrichment_displacements",
69  "Names of enrichment displacement variables (only "
70  "needed if 'use_crack_tip_enrichment=true')");
71  params.addParam<std::vector<BoundaryName>>("cut_off_boundary",
72  "Boundary that contains all nodes for which "
73  "enrichment DOFs should be fixed away from crack tip "
74  "(only needed if 'use_crack_tip_enrichment=true')");
75  params.addParam<Real>("cut_off_radius",
76  "The cut off radius of crack tip enrichment functions (only needed if "
77  "'use_crack_tip_enrichment=true')");
78  return params;
79 }
80 
81 XFEMAction::XFEMAction(InputParameters params)
82  : Action(params),
83  _geom_cut_userobjects(getParam<std::vector<UserObjectName>>("geometric_cut_userobjects")),
84  _xfem_qrule(getParam<std::string>("qrule")),
85  _xfem_cut_plane(false),
86  _xfem_use_crack_growth_increment(getParam<bool>("use_crack_growth_increment")),
87  _xfem_crack_growth_increment(getParam<Real>("crack_growth_increment")),
88  _use_crack_tip_enrichment(getParam<bool>("use_crack_tip_enrichment"))
89 {
90  _order = "CONSTANT";
91  _family = "MONOMIAL";
92  if (isParamValid("output_cut_plane"))
93  _xfem_cut_plane = getParam<bool>("output_cut_plane");
94 
96  {
97  if (isParamValid("crack_front_definition"))
98  _crack_front_definition = getParam<UserObjectName>("crack_front_definition");
99  else
100  mooseError("To add crack tip enrichment, crack_front_definition must be provided.");
101 
102  if (isParamValid("displacements"))
103  _displacements = getParam<std::vector<VariableName>>("displacements");
104  else
105  mooseError("To add crack tip enrichment, displacements must be provided.");
106 
107  if (isParamValid("enrichment_displacements"))
108  {
109  _enrich_displacements = getParam<std::vector<VariableName>>("enrichment_displacements");
110  if (_enrich_displacements.size() != 8 && _displacements.size() == 2)
111  mooseError("The number of enrichment displacements should be total 8 for 2D.");
112  else if (_enrich_displacements.size() != 12 && _displacements.size() == 3)
113  mooseError("The number of enrichment displacements should be total 12 for 3D.");
114  }
115  else
116  mooseError("To add crack tip enrichment, enrichment_displacements must be provided.");
117 
118  if (isParamValid("cut_off_boundary"))
119  _cut_off_bc = getParam<std::vector<BoundaryName>>("cut_off_boundary");
120  else
121  mooseError("To add crack tip enrichment, cut_off_boundary must be provided.");
122 
123  if (isParamValid("cut_off_radius"))
124  _cut_off_radius = getParam<Real>("cut_off_radius");
125  else
126  mooseError("To add crack tip enrichment, cut_off_radius must be provided.");
127  }
128 }
129 
130 void
132 {
133 
134  std::shared_ptr<XFEMInterface> xfem_interface = _problem->getXFEM();
135  if (xfem_interface == NULL)
136  {
137  _pars.set<FEProblemBase *>("_fe_problem_base") = &*_problem;
138  std::shared_ptr<XFEM> new_xfem(new XFEM(_pars));
139  _problem->initXFEM(new_xfem);
140  xfem_interface = _problem->getXFEM();
141  }
142 
143  std::shared_ptr<XFEM> xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(xfem_interface);
144  if (xfem == NULL)
145  mooseError("dynamic cast of xfem object failed");
146 
147  if (_current_task == "setup_xfem")
148  {
149  xfem->setXFEMQRule(_xfem_qrule);
150 
152  xfem->setDebugOutputLevel(getParam<unsigned int>("debug_output_level"));
153  }
154  else if (_current_task == "add_variable" && _use_crack_tip_enrichment)
155  {
156  auto var_params = _factory.getValidParams("MooseVariable");
157  var_params.set<MooseEnum>("family") = "LAGRANGE";
158  var_params.set<MooseEnum>("order") = "FIRST";
159 
160  for (const auto & enrich_disp : _enrich_displacements)
161  _problem->addVariable("MooseVariable", enrich_disp, var_params);
162  }
163  else if (_current_task == "add_kernel" && _use_crack_tip_enrichment)
164  {
165  for (unsigned int i = 0; i < _enrich_displacements.size(); ++i)
166  {
167  InputParameters params = _factory.getValidParams("CrackTipEnrichmentStressDivergenceTensors");
168  params.set<NonlinearVariableName>("variable") = _enrich_displacements[i];
169  params.set<unsigned int>("component") = i / 4;
170  params.set<unsigned int>("enrichment_component") = i % 4;
171  params.set<UserObjectName>("crack_front_definition") = _crack_front_definition;
172  params.set<std::vector<VariableName>>("enrichment_displacements") = _enrich_displacements;
173  params.set<std::vector<VariableName>>("displacements") = _displacements;
174  _problem->addKernel(
175  "CrackTipEnrichmentStressDivergenceTensors", _enrich_displacements[i], params);
176  }
177  }
178  else if (_current_task == "add_bc" && _use_crack_tip_enrichment)
179  {
180  for (unsigned int i = 0; i < _enrich_displacements.size(); ++i)
181  {
182  InputParameters params = _factory.getValidParams("CrackTipEnrichmentCutOffBC");
183  params.set<NonlinearVariableName>("variable") = _enrich_displacements[i];
184  params.set<Real>("value") = 0;
185  params.set<std::vector<BoundaryName>>("boundary") = _cut_off_bc;
186  params.set<Real>("cut_off_radius") = _cut_off_radius;
187  params.set<UserObjectName>("crack_front_definition") = _crack_front_definition;
188  _problem->addBoundaryCondition(
189  "CrackTipEnrichmentCutOffBC", _enrich_displacements[i], params);
190  }
191  }
192  else if (_current_task == "add_aux_variable" && _xfem_cut_plane)
193  {
194  auto var_params = _factory.getValidParams("MooseVariableConstMonomial");
195 
196  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_x", var_params);
197  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_y", var_params);
198  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_z", var_params);
199  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_x", var_params);
200  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_y", var_params);
201  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_z", var_params);
202  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_x", var_params);
203  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_y", var_params);
204  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_z", var_params);
205  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_x", var_params);
206  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_y", var_params);
207  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_z", var_params);
208  _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_volfrac", var_params);
209  }
210  else if (_current_task == "add_aux_kernel" && _xfem_cut_plane)
211  {
212  InputParameters params = _factory.getValidParams("XFEMVolFracAux");
213  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_BEGIN;
214  params.set<AuxVariableName>("variable") = "xfem_volfrac";
215  _problem->addAuxKernel("XFEMVolFracAux", "xfem_volfrac", params);
216 
217  params = _factory.getValidParams("XFEMCutPlaneAux");
218  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
219 
220  // first cut plane
221  params.set<unsigned int>("plane_id") = 0;
222 
223  params.set<AuxVariableName>("variable") = "xfem_cut_origin_x";
224  params.set<MooseEnum>("quantity") = "origin_x";
225  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_x", params);
226 
227  params.set<AuxVariableName>("variable") = "xfem_cut_origin_y";
228  params.set<MooseEnum>("quantity") = "origin_y";
229  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_y", params);
230 
231  params.set<AuxVariableName>("variable") = "xfem_cut_origin_z";
232  params.set<MooseEnum>("quantity") = "origin_z";
233  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_z", params);
234 
235  params.set<AuxVariableName>("variable") = "xfem_cut_normal_x";
236  params.set<MooseEnum>("quantity") = "normal_x";
237  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_x", params);
238 
239  params.set<AuxVariableName>("variable") = "xfem_cut_normal_y";
240  params.set<MooseEnum>("quantity") = "normal_y";
241  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_y", params);
242 
243  params.set<AuxVariableName>("variable") = "xfem_cut_normal_z";
244  params.set<MooseEnum>("quantity") = "normal_z";
245  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_z", params);
246 
247  // second cut plane
248  params.set<unsigned int>("plane_id") = 1;
249 
250  params.set<AuxVariableName>("variable") = "xfem_cut2_origin_x";
251  params.set<MooseEnum>("quantity") = "origin_x";
252  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_x", params);
253 
254  params.set<AuxVariableName>("variable") = "xfem_cut2_origin_y";
255  params.set<MooseEnum>("quantity") = "origin_y";
256  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_y", params);
257 
258  params.set<AuxVariableName>("variable") = "xfem_cut2_origin_z";
259  params.set<MooseEnum>("quantity") = "origin_z";
260  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_z", params);
261 
262  params.set<AuxVariableName>("variable") = "xfem_cut2_normal_x";
263  params.set<MooseEnum>("quantity") = "normal_x";
264  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_x", params);
265 
266  params.set<AuxVariableName>("variable") = "xfem_cut2_normal_y";
267  params.set<MooseEnum>("quantity") = "normal_y";
268  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_y", params);
269 
270  params.set<AuxVariableName>("variable") = "xfem_cut2_normal_z";
271  params.set<MooseEnum>("quantity") = "normal_z";
272  _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_z", params);
273  }
274 }
XFEMAction.h
XFEMAction::_xfem_crack_growth_increment
Real _xfem_crack_growth_increment
Definition: XFEMAction.h:34
XFEMAction::_displacements
std::vector< VariableName > _displacements
Definition: XFEMAction.h:38
validParams< XFEMAction >
InputParameters validParams< XFEMAction >()
Definition: XFEMAction.C:44
XFEMAction
Definition: XFEMAction.h:20
GeometricCutUserObject.h
XFEMAction::_crack_front_definition
UserObjectName _crack_front_definition
Definition: XFEMAction.h:36
CrackFrontDefinition.h
registerMooseAction
registerMooseAction("XFEMApp", XFEMAction, "setup_xfem")
XFEMAction::_family
std::string _family
Definition: XFEMAction.h:31
XFEM.h
XFEMAction::_order
std::string _order
Definition: XFEMAction.h:30
XFEMAction::_xfem_qrule
std::string _xfem_qrule
Definition: XFEMAction.h:29
XFEMAction::act
virtual void act()
Definition: XFEMAction.C:131
XFEMAction::_enrich_displacements
std::vector< VariableName > _enrich_displacements
Definition: XFEMAction.h:37
XFEMAction::_cut_off_radius
Real _cut_off_radius
Definition: XFEMAction.h:40
XFEMAction::_use_crack_tip_enrichment
bool _use_crack_tip_enrichment
Definition: XFEMAction.h:35
XFEMAction::XFEMAction
XFEMAction(InputParameters params)
Definition: XFEMAction.C:81
XFEMAction::_xfem_use_crack_growth_increment
bool _xfem_use_crack_growth_increment
Definition: XFEMAction.h:33
XFEMAction::_xfem_cut_plane
bool _xfem_cut_plane
Definition: XFEMAction.h:32
XFEM
This is the XFEM class.
Definition: XFEM.h:61
XFEMAction::_cut_off_bc
std::vector< BoundaryName > _cut_off_bc
Definition: XFEMAction.h:39