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