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