https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CohesiveZoneAction.C
Go to the documentation of this file.
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 "CohesiveZoneAction.h"
12#include "Factory.h"
13#include "FEProblem.h"
14#include "Conversion.h"
15
16registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_interface_kernel");
17registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_material");
18registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_master_action_material");
19registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_aux_variable");
20registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_aux_kernel");
21registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_kernel");
22registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "validate_coordinate_systems");
23
26{
28 params.addClassDescription("Action to create an instance of the cohesive zone model kernel for "
29 "each displacement component");
30 params.addRequiredParam<std::vector<BoundaryName>>(
31 "boundary", "The list of boundary IDs from the mesh where the cohesive zone will be applied");
32 return params;
33}
34
36 : CohesiveZoneActionBase(params),
37 _displacements(getParam<std::vector<VariableName>>("displacements")),
38 _ndisp(_displacements.size()),
39 _use_AD(getParam<bool>("use_automatic_differentiation")),
40 _base_name(isParamValid("base_name") && !getParam<std::string>("base_name").empty()
41 ? getParam<std::string>("base_name")
42 : ""),
43 _boundary(getParam<std::vector<BoundaryName>>("boundary")),
44 _strain(getParam<MooseEnum>("strain").getEnum<Strain>()),
45 _save_in_primary(getParam<std::vector<AuxVariableName>>("save_in_primary")),
46 _diag_save_in_primary(getParam<std::vector<AuxVariableName>>("diag_save_in_primary")),
47 _save_in_secondary(getParam<std::vector<AuxVariableName>>("save_in_secondary")),
48 _diag_save_in_secondary(getParam<std::vector<AuxVariableName>>("diag_save_in_secondary")),
49 _material_output_order(getParam<MultiMooseEnum>("material_output_order")),
50 _material_output_family(getParam<MultiMooseEnum>("material_output_family")),
51 _verbose(getParam<bool>("verbose"))
52{
53 // We can't enforce consistency between the number of displacement variables and the mesh
54 // dimension. Hence we only check we have a reasonable number of displacement variables
55 if (_ndisp > 3 || _ndisp < 1)
56 mooseError("the CZM Action requires 1, 2 or 3 displacement variables.");
57
58 switch (_strain)
59 {
60 case Strain::Small:
61 {
63 _use_AD ? "ADCZMInterfaceKernelSmallStrain" : "CZMInterfaceKernelSmallStrain";
64 _disp_jump_provider_name = _use_AD ? "ADCZMComputeDisplacementJumpSmallStrain"
65 : "CZMComputeDisplacementJumpSmallStrain";
67 _use_AD ? "ADCZMComputeGlobalTractionSmallStrain" : "CZMComputeGlobalTractionSmallStrain";
68 break;
69 }
70 case Strain::Finite:
71 {
73 _use_AD ? "ADCZMInterfaceKernelTotalLagrangian" : "CZMInterfaceKernelTotalLagrangian";
74 _disp_jump_provider_name = _use_AD ? "ADCZMComputeDisplacementJumpTotalLagrangian"
75 : "CZMComputeDisplacementJumpTotalLagrangian";
76 _equilibrium_traction_calculator_name = _use_AD ? "ADCZMComputeGlobalTractionTotalLagrangian"
77 : "CZMComputeGlobalTractionTotalLagrangian";
78 break;
79 }
80 default:
81 mooseError("CohesiveZoneAction Error: Invalid kinematic parameter. Allowed values are: "
82 "SmallStrain or TotalLagrangian");
83 }
84
85 if (_save_in_primary.size() != 0 && _save_in_primary.size() != _ndisp)
87 "Number of save_in_primary variables should equal to the number of displacement variables ",
88 _ndisp);
89 if (_diag_save_in_primary.size() != 0 && _diag_save_in_primary.size() != _ndisp)
91 "Number of diag_save_in_primary variables should equal to the number of displacement "
92 "variables ",
93 _ndisp);
94 if (_save_in_secondary.size() != 0 && _save_in_secondary.size() != _ndisp)
95 mooseError("Number of save_in_secondary variables should equal to the number of displacement "
96 "variables ",
97 _ndisp);
98
99 if (_diag_save_in_secondary.size() != 0 && _diag_save_in_secondary.size() != _ndisp)
101 "Number of diag_save_in_secondary variables should equal to the number of displacement "
102 "variables ",
103 _ndisp);
104
105 // convert output variable names to lower case
106 for (const auto & out : getParam<MultiMooseEnum>("generate_output"))
107 {
108 std::string lower(out);
109 std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
110 _generate_output.push_back(lower);
111 }
112
113 if (!_generate_output.empty())
115}
116
117void
119{
120 for (unsigned int i = 0; i < _ndisp; ++i)
121 {
122 // Create unique kernel name for each displacement component
123 std::string unique_kernel_name = _czm_kernel_name + "_" + _name + "_" + Moose::stringify(i);
124
126
127 paramsk.set<unsigned int>("component") = i;
128 paramsk.set<NonlinearVariableName>("variable") = _displacements[i];
129 paramsk.set<std::vector<VariableName>>("neighbor_var") = {_displacements[i]};
130 paramsk.set<std::vector<VariableName>>("displacements") = _displacements;
131 paramsk.set<std::vector<BoundaryName>>("boundary") = _boundary;
132 paramsk.set<std::string>("base_name") = _base_name;
133
134 std::string save_in_side;
135 std::vector<AuxVariableName> save_in_var_names;
136 if (_save_in_primary.size() == _ndisp || _save_in_secondary.size() == _ndisp)
137 {
138 prepareSaveInInputs(save_in_var_names, save_in_side, _save_in_primary, _save_in_secondary, i);
139 paramsk.set<std::vector<AuxVariableName>>("save_in") = save_in_var_names;
140 paramsk.set<MultiMooseEnum>("save_in_var_side") = save_in_side;
141 }
143 {
145 save_in_var_names, save_in_side, _diag_save_in_primary, _diag_save_in_secondary, i);
146 paramsk.set<std::vector<AuxVariableName>>("diag_save_in") = save_in_var_names;
147 paramsk.set<MultiMooseEnum>("diag_save_in_var_side") = save_in_side;
148 }
149 _problem->addInterfaceKernel(_czm_kernel_name, unique_kernel_name, paramsk);
150 }
151}
152
153void
155{
156 // Create unique material name for the "CZMComputeDisplacementJump" object
157 std::string unique_material_name = _disp_jump_provider_name + "_" + _name;
159 paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
160
161 paramsm.set<std::vector<VariableName>>("displacements") = _displacements;
162 paramsm.set<std::string>("base_name") = _base_name;
163 _problem->addInterfaceMaterial(_disp_jump_provider_name, unique_material_name, paramsm);
164
165 // Create unique material name for the "CZMComputeGlobalTraction" object
166 unique_material_name = _equilibrium_traction_calculator_name + "_" + _name;
168 paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
169
170 paramsm.set<std::string>("base_name") = _base_name;
171 _problem->addInterfaceMaterial(
172 _equilibrium_traction_calculator_name, unique_material_name, paramsm);
173}
174
175void
177{
178 // Enforce consistency
179 if (_ndisp != _mesh->dimension())
180 paramError("displacements", "Number of displacements must match problem dimension.");
181
183
184 if (_current_task == "add_interface_kernel")
186 else if (_current_task == "add_master_action_material")
188
189 // optional, add required outputs
191}
192
193void
199
200void
201CohesiveZoneAction::prepareSaveInInputs(std::vector<AuxVariableName> & save_in_names,
202 std::string & save_in_side,
203 const std::vector<AuxVariableName> & var_name_primary,
204 const std::vector<AuxVariableName> & var_name_secondary,
205 const int & i) const
206{
207 save_in_names.clear();
208 save_in_side.clear();
209 if (var_name_primary.size() == _ndisp)
210 {
211 save_in_names.push_back(var_name_primary[i]);
212 save_in_side += "m";
213 if (var_name_secondary.size() == _ndisp)
214 save_in_side += " ";
215 }
216 if (var_name_secondary.size() == _ndisp)
217 {
218 save_in_names.push_back(var_name_secondary[i]);
219 save_in_side += "s";
220 }
221}
222
223void
225{
226 // Ensure material output order and family vectors are same size as generate output
227
228 // check number of supplied orders and families
230 paramError("material_output_order",
231 "The number of orders assigned to material outputs must be: 0 to be assigned "
232 "CONSTANT; 1 to assign all outputs the same value, or the same size as the number "
233 "of generate outputs listed.");
234
235 if (_material_output_family.size() > 1 &&
237 paramError("material_output_family",
238 "The number of families assigned to material outputs must be: 0 to be assigned "
239 "MONOMIAL; 1 to assign all outputs the same value, or the same size as the number "
240 "of generate outputs listed.");
241
242 // if no value was provided, chose the default CONSTANT
243 if (_material_output_order.size() == 0)
245
246 // For only one order, make all orders the same magnitude
247 if (_material_output_order.size() == 1)
249 std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
250
251 if (_verbose)
252 Moose::out << COLOR_CYAN << "*** Automatic applied material output orders ***"
253 << "\n"
254 << _name << ": " << Moose::stringify(_material_output_order) << "\n"
255 << COLOR_DEFAULT;
256
257 // if no value was provided, chose the default MONOMIAL
258 if (_material_output_family.size() == 0)
260
261 // For only one family, make all families that value
262 if (_material_output_family.size() == 1)
264 std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
265
266 if (_verbose)
267 Moose::out << COLOR_CYAN << "*** Automatic applied material output families ***"
268 << "\n"
269 << _name << ": " << Moose::stringify(_material_output_family) << "\n"
270 << COLOR_DEFAULT;
271}
272
273void
275{
276 if (_current_task == "add_material")
278
279 // Add variables (optional)
280 if (_current_task == "add_aux_variable")
281 {
282 unsigned int index = 0;
283 for (auto out : _generate_output)
284 {
285 const auto & order = _material_output_order[index];
286 const auto & family = _material_output_family[index];
287
288 std::string type = (order == "CONSTANT" && family == "MONOMIAL")
289 ? "MooseVariableConstMonomial"
290 : "MooseVariable";
291
292 // Create output helper aux variables
293 auto params = _factory.getValidParams(type);
294 params.set<MooseEnum>("order") = order;
295 params.set<MooseEnum>("family") = family;
296 if (family == "MONOMIAL")
297 _problem->addAuxVariable(type, addBaseName(out), params);
298 else
299 _problem->addVariable(type, addBaseName(out), params);
300
301 index++;
302 }
303 }
304
305 // Add output AuxKernels
306 else if (_current_task == "add_aux_kernel")
307 {
308 const std::string material_output_aux_name = _use_AD ? "ADMaterialRealAux" : "MaterialRealAux";
309 // Loop through output aux variables
310 unsigned int index = 0;
311 for (auto out : _generate_output)
312 {
313 if (_material_output_family[index] == "MONOMIAL")
314 {
315 InputParameters params = _factory.getValidParams(material_output_aux_name);
316 params.set<MaterialPropertyName>("property") = addBaseName(out);
317 params.set<AuxVariableName>("variable") = addBaseName(out);
318 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
319 params.set<std::vector<BoundaryName>>("boundary") = _boundary;
320 params.set<bool>("check_boundary_restricted") = false;
321 _problem->addAuxKernel(material_output_aux_name, addBaseName(out) + '_' + name(), params);
322 }
323 index++;
324 }
325 }
326}
327
328void
330{
331 if (_current_task == "add_material")
332 {
333 // Add output Materials
334 for (auto out : _generate_output)
335 {
337
338 // RealVectorCartesianComponent
339 if (
340 [&]()
341 {
342 for (const auto & vq : _real_vector_cartesian_component_table)
343 for (unsigned int a = 0; a < 3; ++a)
344 if (vq.first + '_' + _component_table[a] == out)
345 {
346 auto type = _use_AD ? "ADCZMRealVectorCartesianComponent"
347 : "CZMRealVectorCartesianComponent";
348 params = _factory.getValidParams(type);
349 params.set<std::string>("real_vector_value") = vq.second;
350 params.set<unsigned int>("index") = a;
351 params.set<std::vector<BoundaryName>>("boundary") = _boundary;
352 params.set<MaterialPropertyName>("property_name") = addBaseName(out);
353 params.set<std::string>("base_name") = _base_name;
354 _problem->addInterfaceMaterial(type, addBaseName(out) + '_' + name(), params);
355 return true;
356 }
357 return false;
358 }())
359 continue;
360
361 // CZMRealVectorScalar
362 if (setupOutput(out,
364 [&](std::string prop_name, std::string direction)
365 {
366 auto type = _use_AD ? "ADCZMRealVectorScalar" : "CZMRealVectorScalar";
367 params = _factory.getValidParams(type);
368 params.set<std::string>("real_vector_value") = prop_name;
369 params.set<MooseEnum>("direction") = direction;
370 params.set<MaterialPropertyName>("property_name") = addBaseName(out);
371 params.set<std::vector<BoundaryName>>("boundary") = _boundary;
372 params.set<std::string>("base_name") = _base_name;
373 _problem->addInterfaceMaterial(
374 type, addBaseName(out) + '_' + name(), params);
375 }))
376 continue;
377
378 mooseError("CZM Master: unable to add output Material");
379 }
380 }
381}
382
383void
385{
386
387 // Gather info about all other master actions when we add variables
388 if (_current_task == "validate_coordinate_systems")
389 {
390 auto actions = _awh.getActions<CohesiveZoneAction>();
391 for (const auto & action : actions)
392 {
393 const auto size_before = _boundary_name_union.size();
394 const auto added_size = action->_boundary.size();
395 _boundary_name_union.insert(action->_boundary.begin(), action->_boundary.end());
396 const auto size_after = _boundary_name_union.size();
397 if (size_after != size_before + added_size)
398 mooseError("The boundary restrictions in the CohesiveZoneAction actions must be "
399 "non-overlapping.");
400 }
401
402 for (const auto & action : actions)
403 {
404 // check for different strain definitions
405 _strain_formulation_union.insert(action->_strain);
406 const auto size_after = _strain_formulation_union.size();
407
408 if (size_after != 1)
409 mooseError("All blocks of the CohesiveZoneAction should have the same strain formulation");
410 }
411 }
412}
registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_interface_kernel")
InputParameters emptyInputParameters()
const ExecFlagType EXEC_TIMESTEP_END
std::vector< const T * > getActions()
std::shared_ptr< MooseMesh > & _mesh
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
ActionWarehouse & _awh
static const std::vector< char > _component_table
static const std::map< std::string, std::string > _real_vector_cartesian_component_table
table data for output generation
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _vector_direction_table
static InputParameters validParams()
const unsigned int _ndisp
number of displacement components
std::vector< AuxVariableName > _diag_save_in_secondary
std::vector< std::string > _generate_output
output materials to generate scalar traction/jump vector quantities
std::vector< AuxVariableName > _save_in_primary
residual debugging
const bool _use_AD
whether to use AD kernels and materials
std::vector< VariableName > _displacements
the disaplcements varaible names
std::vector< AuxVariableName > _diag_save_in_primary
const std::string _base_name
Base name of the material system.
Strain
strain formulation
const bool _verbose
display info
std::string _equilibrium_traction_calculator_name
void prepareSaveInInputs(std::vector< AuxVariableName > &, std::string &, const std::vector< AuxVariableName > &, const std::vector< AuxVariableName > &, const int &) const
method to prepare save_in and diag_save_in inputs for the interface kernel
std::set< BoundaryName > _boundary_name_union
set generated from the combined boundary restrictions of all CohesiveZoneAction action blocks
void addRequiredCZMInterfaceMaterials()
adds the required interface materials based on the selected strain formulation
std::set< Strain > _strain_formulation_union
set generated from the combined boundary restrictions of all CohesiveZoneAction action blocks
std::string addBaseName(const std::string &name) const
simple method for adding the base name to a variable
void chekMultipleActionParameters()
method checking multiple CohesiveZoneAction block inputs
std::vector< AuxVariableName > _save_in_secondary
static InputParameters validParams()
std::string _disp_jump_provider_name
CohesiveZoneAction(const InputParameters &params)
bool setupOutput(std::string out, T table, T2 setup)
enum CohesiveZoneAction::Strain _strain
MultiMooseEnum _material_output_order
MultiMooseEnum _material_output_family
void addRequiredCZMInterfaceKernels()
adds the required interfacekernels based on the selected strain formulation
virtual void addRelationshipManagers(Moose::RelationshipManagerType input_rm_type) override
std::string _czm_kernel_name
kernel's and materials's names
void verifyOrderAndFamilyOutputs()
verifies order and family of output variables
const std::vector< BoundaryName > _boundary
Base name of the material system.
InputParameters getValidParams(const std::string &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
const std::string & type() const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
const std::string & _name
void setAdditionalValue(const std::string &names)
unsigned int size() const
Factory & _factory
std::string stringify(const T &t)
RelationshipManagerType