Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
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"
21 : #include "InputParameterWarehouse.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 :
44 : InputParameters
45 421 : XFEMAction::validParams()
46 : {
47 421 : InputParameters params = Action::validParams();
48 :
49 842 : params.addParam<std::vector<UserObjectName>>(
50 : "geometric_cut_userobjects",
51 : {},
52 : "List of names of GeometricCutUserObjects with cut info and methods");
53 842 : params.addParam<std::string>("qrule", "volfrac", "XFEM quadrature rule to use");
54 1263 : params.addRangeCheckedParam<unsigned int>(
55 : "debug_output_level",
56 842 : 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 842 : params.addParam<bool>("output_cut_plane", false, "Output the XFEM cut plane and volume fraction");
61 842 : params.addParam<bool>("use_crack_growth_increment", false, "Use fixed crack growth increment");
62 842 : params.addParam<Real>("crack_growth_increment", 0.1, "Crack growth increment");
63 842 : params.addParam<bool>("use_crack_tip_enrichment", false, "Use crack tip enrichment functions");
64 842 : params.addParam<UserObjectName>("crack_front_definition",
65 : "The CrackFrontDefinition user object name (only "
66 : "needed if 'use_crack_tip_enrichment=true')");
67 842 : params.addParam<std::vector<VariableName>>("displacements",
68 : "Names of displacement variables (only "
69 : "needed if 'use_crack_tip_enrichment=true')");
70 842 : params.addParam<std::vector<VariableName>>("enrichment_displacements",
71 : "Names of enrichment displacement variables (only "
72 : "needed if 'use_crack_tip_enrichment=true')");
73 842 : 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 842 : 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 421 : params.addClassDescription("Action to input general parameters and simulation options for use "
81 : "in XFEM.");
82 421 : return params;
83 0 : }
84 :
85 421 : XFEMAction::XFEMAction(const InputParameters & params)
86 : : Action(params),
87 421 : _geom_cut_userobjects(getParam<std::vector<UserObjectName>>("geometric_cut_userobjects")),
88 1263 : _xfem_qrule(getParam<std::string>("qrule")),
89 421 : _xfem_cut_plane(false),
90 842 : _xfem_use_crack_growth_increment(getParam<bool>("use_crack_growth_increment")),
91 842 : _xfem_crack_growth_increment(getParam<Real>("crack_growth_increment")),
92 1263 : _use_crack_tip_enrichment(getParam<bool>("use_crack_tip_enrichment"))
93 : {
94 421 : _order = "CONSTANT";
95 421 : _family = "MONOMIAL";
96 842 : if (isParamValid("output_cut_plane"))
97 842 : _xfem_cut_plane = getParam<bool>("output_cut_plane");
98 :
99 421 : if (_use_crack_tip_enrichment)
100 : {
101 8 : if (isParamValid("crack_front_definition"))
102 4 : _crack_front_definition = getParam<UserObjectName>("crack_front_definition");
103 : else
104 0 : mooseError("To add crack tip enrichment, crack_front_definition must be provided.");
105 :
106 8 : if (isParamValid("displacements"))
107 8 : _displacements = getParam<std::vector<VariableName>>("displacements");
108 : else
109 0 : mooseError("To add crack tip enrichment, displacements must be provided.");
110 :
111 8 : if (isParamValid("enrichment_displacements"))
112 : {
113 12 : _enrich_displacements = getParam<std::vector<VariableName>>("enrichment_displacements");
114 4 : if (_enrich_displacements.size() != 8 && _displacements.size() == 2)
115 0 : mooseError("The number of enrichment displacements should be total 8 for 2D.");
116 4 : else if (_enrich_displacements.size() != 12 && _displacements.size() == 3)
117 0 : mooseError("The number of enrichment displacements should be total 12 for 3D.");
118 : }
119 : else
120 0 : mooseError("To add crack tip enrichment, enrichment_displacements must be provided.");
121 :
122 8 : if (isParamValid("cut_off_boundary"))
123 8 : _cut_off_bc = getParam<std::vector<BoundaryName>>("cut_off_boundary");
124 : else
125 0 : mooseError("To add crack tip enrichment, cut_off_boundary must be provided.");
126 :
127 8 : if (isParamValid("cut_off_radius"))
128 8 : _cut_off_radius = getParam<Real>("cut_off_radius");
129 : else
130 0 : mooseError("To add crack tip enrichment, cut_off_radius must be provided.");
131 : }
132 421 : }
133 :
134 : void
135 2522 : XFEMAction::act()
136 : {
137 :
138 2522 : std::shared_ptr<XFEMInterface> xfem_interface = _problem->getXFEM();
139 2522 : if (xfem_interface == nullptr)
140 : {
141 421 : const auto & params = _app.getInputParameterWarehouse().getInputParameters();
142 421 : InputParameters & pars(*(params.find(uniqueActionName())->second.get()));
143 421 : pars.set<FEProblemBase *>("_fe_problem_base") = &*_problem;
144 421 : std::shared_ptr<XFEM> new_xfem(new XFEM(_pars));
145 842 : _problem->initXFEM(new_xfem);
146 842 : xfem_interface = _problem->getXFEM();
147 : }
148 :
149 2522 : std::shared_ptr<XFEM> xfem = MooseSharedNamespace::dynamic_pointer_cast<XFEM>(xfem_interface);
150 2522 : if (xfem == nullptr)
151 0 : mooseError("dynamic cast of xfem object failed");
152 :
153 2522 : if (_current_task == "setup_xfem")
154 : {
155 420 : xfem->setXFEMQRule(_xfem_qrule);
156 :
157 420 : xfem->setCrackGrowthMethod(_xfem_use_crack_growth_increment, _xfem_crack_growth_increment);
158 1260 : xfem->setDebugOutputLevel(getParam<unsigned int>("debug_output_level"));
159 : }
160 2102 : else if (_current_task == "add_variable" && _use_crack_tip_enrichment)
161 : {
162 4 : auto var_params = _factory.getValidParams("MooseVariable");
163 8 : var_params.set<MooseEnum>("family") = "LAGRANGE";
164 8 : var_params.set<MooseEnum>("order") = "FIRST";
165 :
166 36 : for (const auto & enrich_disp : _enrich_displacements)
167 64 : _problem->addVariable("MooseVariable", enrich_disp, var_params);
168 4 : }
169 2098 : else if (_current_task == "add_kernel" && _use_crack_tip_enrichment)
170 : {
171 36 : for (unsigned int i = 0; i < _enrich_displacements.size(); ++i)
172 : {
173 64 : InputParameters params = _factory.getValidParams("CrackTipEnrichmentStressDivergenceTensors");
174 64 : params.set<NonlinearVariableName>("variable") = _enrich_displacements[i];
175 32 : params.set<unsigned int>("component") = i / 4;
176 32 : params.set<unsigned int>("enrichment_component") = i % 4;
177 32 : params.set<UserObjectName>("crack_front_definition") = _crack_front_definition;
178 32 : params.set<std::vector<VariableName>>("enrichment_displacements") = _enrich_displacements;
179 32 : params.set<std::vector<VariableName>>("displacements") = _displacements;
180 32 : _problem->addKernel(
181 : "CrackTipEnrichmentStressDivergenceTensors", _enrich_displacements[i], params);
182 32 : }
183 : }
184 2094 : else if (_current_task == "add_bc" && _use_crack_tip_enrichment)
185 : {
186 36 : for (unsigned int i = 0; i < _enrich_displacements.size(); ++i)
187 : {
188 64 : InputParameters params = _factory.getValidParams("CrackTipEnrichmentCutOffBC");
189 64 : params.set<NonlinearVariableName>("variable") = _enrich_displacements[i];
190 32 : params.set<Real>("value") = 0;
191 32 : params.set<std::vector<BoundaryName>>("boundary") = _cut_off_bc;
192 32 : params.set<Real>("cut_off_radius") = _cut_off_radius;
193 32 : params.set<UserObjectName>("crack_front_definition") = _crack_front_definition;
194 32 : _problem->addBoundaryCondition(
195 : "CrackTipEnrichmentCutOffBC", _enrich_displacements[i], params);
196 32 : }
197 : }
198 2090 : else if (_current_task == "add_aux_variable" && _xfem_cut_plane)
199 : {
200 421 : auto var_params = _factory.getValidParams("MooseVariableConstMonomial");
201 :
202 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_x", var_params);
203 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_y", var_params);
204 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_origin_z", var_params);
205 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_x", var_params);
206 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_y", var_params);
207 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut_normal_z", var_params);
208 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_x", var_params);
209 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_y", var_params);
210 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_origin_z", var_params);
211 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_x", var_params);
212 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_y", var_params);
213 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_cut2_normal_z", var_params);
214 842 : _problem->addAuxVariable("MooseVariableConstMonomial", "xfem_volfrac", var_params);
215 421 : }
216 1669 : else if (_current_task == "add_aux_kernel" && _xfem_cut_plane)
217 : {
218 420 : InputParameters params = _factory.getValidParams("XFEMVolFracAux");
219 840 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_BEGIN;
220 840 : params.set<AuxVariableName>("variable") = "xfem_volfrac";
221 840 : _problem->addAuxKernel("XFEMVolFracAux", "xfem_volfrac", params);
222 :
223 420 : params = _factory.getValidParams("XFEMCutPlaneAux");
224 420 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
225 :
226 : // first cut plane
227 420 : params.set<unsigned int>("plane_id") = 0;
228 :
229 840 : params.set<AuxVariableName>("variable") = "xfem_cut_origin_x";
230 840 : params.set<MooseEnum>("quantity") = "origin_x";
231 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_x", params);
232 :
233 840 : params.set<AuxVariableName>("variable") = "xfem_cut_origin_y";
234 840 : params.set<MooseEnum>("quantity") = "origin_y";
235 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_y", params);
236 :
237 840 : params.set<AuxVariableName>("variable") = "xfem_cut_origin_z";
238 840 : params.set<MooseEnum>("quantity") = "origin_z";
239 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_origin_z", params);
240 :
241 840 : params.set<AuxVariableName>("variable") = "xfem_cut_normal_x";
242 840 : params.set<MooseEnum>("quantity") = "normal_x";
243 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_x", params);
244 :
245 840 : params.set<AuxVariableName>("variable") = "xfem_cut_normal_y";
246 840 : params.set<MooseEnum>("quantity") = "normal_y";
247 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_y", params);
248 :
249 840 : params.set<AuxVariableName>("variable") = "xfem_cut_normal_z";
250 840 : params.set<MooseEnum>("quantity") = "normal_z";
251 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut_normal_z", params);
252 :
253 : // second cut plane
254 420 : params.set<unsigned int>("plane_id") = 1;
255 :
256 840 : params.set<AuxVariableName>("variable") = "xfem_cut2_origin_x";
257 840 : params.set<MooseEnum>("quantity") = "origin_x";
258 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_x", params);
259 :
260 840 : params.set<AuxVariableName>("variable") = "xfem_cut2_origin_y";
261 840 : params.set<MooseEnum>("quantity") = "origin_y";
262 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_y", params);
263 :
264 840 : params.set<AuxVariableName>("variable") = "xfem_cut2_origin_z";
265 840 : params.set<MooseEnum>("quantity") = "origin_z";
266 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_origin_z", params);
267 :
268 840 : params.set<AuxVariableName>("variable") = "xfem_cut2_normal_x";
269 840 : params.set<MooseEnum>("quantity") = "normal_x";
270 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_x", params);
271 :
272 840 : params.set<AuxVariableName>("variable") = "xfem_cut2_normal_y";
273 840 : params.set<MooseEnum>("quantity") = "normal_y";
274 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_y", params);
275 :
276 840 : params.set<AuxVariableName>("variable") = "xfem_cut2_normal_z";
277 840 : params.set<MooseEnum>("quantity") = "normal_z";
278 840 : _problem->addAuxKernel("XFEMCutPlaneAux", "xfem_cut2_normal_z", params);
279 420 : }
280 2522 : }
|