https://mooseframework.inl.gov
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"
11 #include "AddAuxVariableAction.h"
12 #include "Factory.h"
13 #include "FEProblem.h"
14 #include "Conversion.h"
15 
16 registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_interface_kernel");
17 registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_material");
18 registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_master_action_material");
19 registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_aux_variable");
20 registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_aux_kernel");
21 registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_kernel");
22 registerMooseAction("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)
86  mooseError(
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)
90  mooseError(
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)
100  mooseError(
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 
117 void
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  }
142  if (_diag_save_in_primary.size() == _ndisp || _diag_save_in_secondary.size() == _ndisp)
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 
153 void
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 
175 void
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 
193 void
195 {
197  addRelationshipManagers(input_rm_type, ips);
198 }
199 
200 void
201 CohesiveZoneAction::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 
223 void
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 
273 void
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 
328 void
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 
383 void
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 }
std::string _equilibrium_traction_calculator_name
std::vector< AuxVariableName > _save_in_secondary
static InputParameters validParams()
RelationshipManagerType
const std::string & _name
ActionWarehouse & _awh
void paramError(const std::string &param, Args... args) const
MultiMooseEnum _material_output_family
void chekMultipleActionParameters()
method checking multiple CohesiveZoneAction block inputs
registerMooseAction("SolidMechanicsApp", CohesiveZoneAction, "add_interface_kernel")
static const std::vector< char > _component_table
void setAdditionalValue(const std::string &names)
Factory & _factory
std::vector< AuxVariableName > _diag_save_in_primary
Strain
strain formulation
std::vector< AuxVariableName > _save_in_primary
residual debugging
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
void addRequiredCZMInterfaceMaterials()
adds the required interface materials based on the selected strain formulation
unsigned int size() const
std::string _disp_jump_provider_name
std::vector< AuxVariableName > _diag_save_in_secondary
const ExecFlagType EXEC_TIMESTEP_END
void addRequiredParam(const std::string &name, const std::string &doc_string)
InputParameters emptyInputParameters()
std::vector< std::string > _generate_output
output materials to generate scalar traction/jump vector quantities
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
const std::string _base_name
Base name of the material system.
MultiMooseEnum _material_output_order
const bool _verbose
display info
static const std::map< std::string, std::string > _real_vector_cartesian_component_table
table data for output generation
static InputParameters validParams()
const std::string & name() const
void addRequiredCZMInterfaceKernels()
adds the required interfacekernels based on the selected strain formulation
std::vector< VariableName > _displacements
the disaplcements varaible names
const std::string & type() const
const std::string & _current_task
const unsigned int _ndisp
number of displacement components
std::string stringify(const T &t)
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
std::shared_ptr< MooseMesh > & _mesh
virtual void addRelationshipManagers(Moose::RelationshipManagerType input_rm_type) override
OStreamProxy out
std::set< BoundaryName > _boundary_name_union
set generated from the combined boundary restrictions of all CohesiveZoneAction action blocks ...
void verifyOrderAndFamilyOutputs()
verifies order and family of output variables
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
std::shared_ptr< FEProblemBase > & _problem
CohesiveZoneAction(const InputParameters &params)
std::string _czm_kernel_name
kernel&#39;s and materials&#39;s names
std::vector< const T *> getActions()
const bool _use_AD
whether to use AD kernels and materials
enum CohesiveZoneAction::Strain _strain
const std::vector< BoundaryName > _boundary
Base name of the material system.
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _vector_direction_table
bool setupOutput(std::string out, T table, T2 setup)