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