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 "Factory.h"
11 : #include "FEProblemBase.h"
12 : #include "Conversion.h"
13 : #include "MooseObjectAction.h"
14 : #include "MechanicsActionPD.h"
15 :
16 : #include "libmesh/string_to_enum.h"
17 :
18 : registerMooseAction("PeridynamicsApp", MechanicsActionPD, "setup_mesh_complete");
19 : registerMooseAction("PeridynamicsApp", MechanicsActionPD, "create_problem_complete");
20 : registerMooseAction("PeridynamicsApp", MechanicsActionPD, "add_aux_variable");
21 : registerMooseAction("PeridynamicsApp", MechanicsActionPD, "add_user_object");
22 : registerMooseAction("PeridynamicsApp", MechanicsActionPD, "add_ic");
23 : registerMooseAction("PeridynamicsApp", MechanicsActionPD, "add_kernel");
24 :
25 : InputParameters
26 253 : MechanicsActionPD::validParams()
27 : {
28 253 : InputParameters params = Action::validParams();
29 253 : params.addClassDescription("Class for setting up peridynamic kernels");
30 :
31 506 : params.addRequiredParam<std::vector<VariableName>>(
32 : "displacements", "Nonlinear variable names for the displacements");
33 506 : MooseEnum formulation_option("BOND ORDINARY_STATE NONORDINARY_STATE");
34 506 : params.addRequiredParam<MooseEnum>(
35 : "formulation", formulation_option, "Peridynamic formulation options");
36 506 : MooseEnum stabilization_option("FORCE BOND_HORIZON_I BOND_HORIZON_II");
37 506 : params.addParam<MooseEnum>("stabilization",
38 : stabilization_option,
39 : "Stabilization techniques for the peridynamic correspondence model");
40 506 : params.addParam<bool>(
41 : "full_jacobian",
42 506 : false,
43 : "Parameter to set whether to use full jacobian for state based formulation or not");
44 506 : MooseEnum strain_type("SMALL FINITE", "SMALL");
45 506 : params.addParam<MooseEnum>("strain", strain_type, "Strain formulation");
46 506 : params.addParam<VariableName>("temperature", "Nonlinear variable name for the temperature");
47 506 : params.addParam<VariableName>("out_of_plane_strain",
48 : "Nonlinear variable name for the out_of_plane strain for "
49 : "plane stress using the NOSPD formulation");
50 506 : params.addParam<std::vector<SubdomainName>>("block",
51 : {},
52 : "List of ids of the blocks (subdomains) that the "
53 : "peridynamic mechanics kernel will be applied to");
54 506 : params.addParam<std::vector<AuxVariableName>>("save_in", {}, "The displacement residuals");
55 506 : params.addParam<std::vector<AuxVariableName>>(
56 : "diag_save_in", {}, "The displacement diagonal preconditioner terms");
57 506 : params.addParam<std::vector<MaterialPropertyName>>(
58 : "eigenstrain_names",
59 : {},
60 : "List of eigenstrains to be coupled in non-ordinary state-based mechanics kernels");
61 :
62 253 : return params;
63 253 : }
64 :
65 253 : MechanicsActionPD::MechanicsActionPD(const InputParameters & params)
66 : : Action(params),
67 506 : _displacements(getParam<std::vector<VariableName>>("displacements")),
68 253 : _ndisp(_displacements.size()),
69 506 : _formulation(getParam<MooseEnum>("formulation")),
70 506 : _stabilization(getParam<MooseEnum>("stabilization")),
71 506 : _strain(getParam<MooseEnum>("strain")),
72 759 : _subdomain_names(getParam<std::vector<SubdomainName>>("block")),
73 : _subdomain_ids(),
74 506 : _save_in(getParam<std::vector<AuxVariableName>>("save_in")),
75 759 : _diag_save_in(getParam<std::vector<AuxVariableName>>("diag_save_in"))
76 : {
77 : // Consistency check
78 613 : if (_formulation == "NONORDINARY_STATE" && !isParamValid("stabilization"))
79 0 : mooseError("'stabilization' is a required parameter for non-ordinary state-based models only.");
80 :
81 253 : if (_save_in.size() != 0 && _save_in.size() != _ndisp)
82 0 : mooseError("Number of save_in variables should equal to the number of displacement variables ",
83 0 : _ndisp);
84 :
85 253 : if (_diag_save_in.size() != 0 && _diag_save_in.size() != _ndisp)
86 0 : mooseError(
87 : "Number of diag_save_in variables should equal to the number of displacement variables ",
88 0 : _ndisp);
89 253 : }
90 :
91 : void
92 1518 : MechanicsActionPD::act()
93 : {
94 1518 : if (_current_task == "setup_mesh_complete")
95 : {
96 : // get subdomain IDs
97 263 : for (auto & name : _subdomain_names)
98 10 : _subdomain_ids.insert(_mesh->getSubdomainID(name));
99 : }
100 1265 : else if (_current_task == "create_problem_complete")
101 : {
102 : // Gather info about all other master actions for adding (aux)variables
103 253 : auto actions = _awh.getActions<MechanicsActionPD>();
104 516 : for (const auto & action : actions)
105 : {
106 : const auto size_before = _subdomain_id_union.size();
107 263 : const auto added_size = action->_subdomain_ids.size();
108 263 : _subdomain_id_union.insert(action->_subdomain_ids.begin(), action->_subdomain_ids.end());
109 : const auto size_after = _subdomain_id_union.size();
110 :
111 263 : if (size_after != size_before + added_size)
112 0 : mooseError("The block restrictions in the Peridynamics/Mechanics/Master actions must be "
113 : "non-overlapping!");
114 :
115 263 : if (added_size == 0 && actions.size() > 1)
116 0 : mooseError(
117 : "No Peridynamics/Mechanics/Master action can be block unrestricted if more than one "
118 : "Peridynamics/Mechanics/Master action is specified!");
119 : }
120 253 : }
121 1012 : else if (_current_task == "add_aux_variable")
122 : {
123 : // add the bond_status aux variable to all peridynamic domains
124 253 : const std::string var_type = "MooseVariableConstMonomial";
125 253 : InputParameters params = _factory.getValidParams(var_type);
126 506 : params.set<MooseEnum>("order") = "CONSTANT";
127 506 : params.set<MooseEnum>("family") = "MONOMIAL";
128 :
129 253 : if (!_subdomain_id_union.empty())
130 30 : for (const SubdomainID & id : _subdomain_id_union)
131 40 : params.set<std::vector<SubdomainName>>("block").push_back(Moose::stringify(id));
132 :
133 253 : _problem->addAuxVariable(var_type, "bond_status", params);
134 253 : }
135 759 : else if (_current_task == "add_ic")
136 : {
137 253 : const std::string ic_type = "ConstantIC";
138 253 : const std::string ic_name = name() + "bond_status";
139 :
140 253 : InputParameters params = _factory.getValidParams(ic_type);
141 506 : params.set<VariableName>("variable") = "bond_status";
142 253 : params.set<Real>("value") = 1.0;
143 :
144 : // check whether this object is restricted to certain block?
145 506 : if (isParamValid("block"))
146 506 : params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
147 :
148 253 : _problem->addInitialCondition(ic_type, ic_name, params);
149 253 : }
150 506 : else if (_current_task == "add_user_object")
151 : {
152 : // add ghosting UO
153 253 : const std::string uo_type = "GhostElemPD";
154 253 : const std::string uo_name = name() + "GhostElemPD";
155 :
156 253 : InputParameters params = _factory.getValidParams(uo_type);
157 253 : params.set<bool>("use_displaced_mesh") = (_strain == "FINITE");
158 :
159 253 : _problem->addUserObject(uo_type, uo_name, params);
160 253 : }
161 253 : else if (_current_task == "add_kernel")
162 : {
163 253 : const std::string kernel_name = getKernelName();
164 253 : InputParameters params = getKernelParameters(kernel_name);
165 :
166 775 : for (unsigned int i = 0; i < _ndisp; ++i)
167 : {
168 1044 : const std::string kernel_object_name = name() + "Peridynamics_" + Moose::stringify(i);
169 :
170 522 : params.set<unsigned int>("component") = i;
171 1044 : params.set<NonlinearVariableName>("variable") = _displacements[i];
172 :
173 522 : if (_save_in.size() != 0)
174 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
175 522 : if (_diag_save_in.size() != 0)
176 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
177 :
178 522 : _problem->addKernel(kernel_name, kernel_object_name, params);
179 : }
180 253 : }
181 : else
182 0 : mooseError("Task error in MechanicsActionPD!");
183 1518 : }
184 :
185 : std::string
186 253 : MechanicsActionPD::getKernelName()
187 : {
188 : std::string name;
189 :
190 253 : if (_formulation == "BOND")
191 : {
192 : name = "MechanicsBPD";
193 : }
194 202 : else if (_formulation == "ORDINARY_STATE")
195 : {
196 : name = "MechanicsOSPD";
197 : }
198 120 : else if (_formulation == "NONORDINARY_STATE")
199 : {
200 120 : if (_stabilization == "FORCE")
201 : {
202 : name = "ForceStabilizedSmallStrainMechanicsNOSPD";
203 : }
204 104 : else if (_stabilization == "BOND_HORIZON_I")
205 : {
206 92 : if (_strain == "SMALL")
207 : name = "HorizonStabilizedFormISmallStrainMechanicsNOSPD";
208 : else
209 : name = "HorizonStabilizedFormIFiniteStrainMechanicsNOSPD";
210 : }
211 12 : else if (_stabilization == "BOND_HORIZON_II")
212 : {
213 12 : if (_strain == "SMALL")
214 : name = "HorizonStabilizedFormIISmallStrainMechanicsNOSPD";
215 : else
216 : name = "HorizonStabilizedFormIIFiniteStrainMechanicsNOSPD";
217 : }
218 : else
219 0 : paramError("stabilization", "Unknown PD stabilization scheme!");
220 : }
221 : else
222 0 : paramError("formulation", "Unsupported peridynamic formulation!");
223 :
224 253 : return name;
225 : }
226 :
227 : InputParameters
228 253 : MechanicsActionPD::getKernelParameters(std::string name)
229 : {
230 253 : InputParameters params = _factory.getValidParams(name);
231 :
232 253 : params.applyParameters(parameters(),
233 : {"displacements",
234 : "temperature",
235 : "out_of_plane_strain",
236 : "eigenstrain_names",
237 : "use_displaced_mesh",
238 : "save_in",
239 : "diag_save_in"});
240 :
241 253 : params.set<std::vector<VariableName>>("displacements") = _displacements;
242 506 : if (isParamValid("temperature"))
243 210 : params.set<std::vector<VariableName>>("temperature") = {getParam<VariableName>("temperature")};
244 506 : if (isParamValid("out_of_plane_strain"))
245 26 : params.set<std::vector<VariableName>>("out_of_plane_strain") = {
246 52 : getParam<VariableName>("out_of_plane_strain")};
247 :
248 : // peridynamics modules are formulated based on initial configuration
249 253 : params.set<bool>("use_displaced_mesh") = false;
250 :
251 493 : if (_formulation == "NONORDINARY_STATE" && isParamValid("eigenstrain_names"))
252 : {
253 240 : params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") =
254 360 : getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
255 : }
256 :
257 253 : return params;
258 166 : }
|