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_master(getParam<std::vector<AuxVariableName>>("save_in_master")),
46  _diag_save_in_master(getParam<std::vector<AuxVariableName>>("diag_save_in_master")),
47  _save_in_slave(getParam<std::vector<AuxVariableName>>("save_in_slave")),
48  _diag_save_in_slave(getParam<std::vector<AuxVariableName>>("diag_save_in_slave")),
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_master.size() != 0 && _save_in_master.size() != _ndisp)
86  mooseError(
87  "Number of save_in_master variables should equal to the number of displacement variables ",
88  _ndisp);
89  if (_diag_save_in_master.size() != 0 && _diag_save_in_master.size() != _ndisp)
90  mooseError("Number of diag_save_in_master variables should equal to the number of displacement "
91  "variables ",
92  _ndisp);
93  if (_save_in_slave.size() != 0 && _save_in_slave.size() != _ndisp)
94  mooseError(
95  "Number of save_in_slave variables should equal to the number of displacement variables ",
96  _ndisp);
97 
98  if (_diag_save_in_slave.size() != 0 && _diag_save_in_slave.size() != _ndisp)
99  mooseError("Number of diag_save_in_slave variables should equal to the number of displacement "
100  "variables ",
101  _ndisp);
102 
103  // convert output variable names to lower case
104  for (const auto & out : getParam<MultiMooseEnum>("generate_output"))
105  {
106  std::string lower(out);
107  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
108  _generate_output.push_back(lower);
109  }
110 
111  if (!_generate_output.empty())
113 }
114 
115 void
117 {
118  for (unsigned int i = 0; i < _ndisp; ++i)
119  {
120  // Create unique kernel name for each displacement component
121  std::string unique_kernel_name = _czm_kernel_name + "_" + _name + "_" + Moose::stringify(i);
122 
124 
125  paramsk.set<unsigned int>("component") = i;
126  paramsk.set<NonlinearVariableName>("variable") = _displacements[i];
127  paramsk.set<std::vector<VariableName>>("neighbor_var") = {_displacements[i]};
128  paramsk.set<std::vector<VariableName>>("displacements") = _displacements;
129  paramsk.set<std::vector<BoundaryName>>("boundary") = _boundary;
130  paramsk.set<std::string>("base_name") = _base_name;
131 
132  std::string save_in_side;
133  std::vector<AuxVariableName> save_in_var_names;
134  if (_save_in_master.size() == _ndisp || _save_in_slave.size() == _ndisp)
135  {
136  prepareSaveInInputs(save_in_var_names, save_in_side, _save_in_master, _save_in_slave, i);
137  paramsk.set<std::vector<AuxVariableName>>("save_in") = save_in_var_names;
138  paramsk.set<MultiMooseEnum>("save_in_var_side") = save_in_side;
139  }
140  if (_diag_save_in_master.size() == _ndisp || _diag_save_in_slave.size() == _ndisp)
141  {
143  save_in_var_names, save_in_side, _diag_save_in_master, _diag_save_in_slave, i);
144  paramsk.set<std::vector<AuxVariableName>>("diag_save_in") = save_in_var_names;
145  paramsk.set<MultiMooseEnum>("diag_save_in_var_side") = save_in_side;
146  }
147  _problem->addInterfaceKernel(_czm_kernel_name, unique_kernel_name, paramsk);
148  }
149 }
150 
151 void
153 {
154  // Create unique material name for the "CZMComputeDisplacementJump" object
155  std::string unique_material_name = _disp_jump_provider_name + "_" + _name;
157  paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
158  ;
159  paramsm.set<std::vector<VariableName>>("displacements") = _displacements;
160  paramsm.set<std::string>("base_name") = _base_name;
161  _problem->addInterfaceMaterial(_disp_jump_provider_name, unique_material_name, paramsm);
162 
163  // Create unique material name for the "CZMComputeGlobalTraction" object
164  unique_material_name = _equilibrium_traction_calculator_name + "_" + _name;
166  paramsm.set<std::vector<BoundaryName>>("boundary") = _boundary;
167  ;
168  paramsm.set<std::string>("base_name") = _base_name;
169  _problem->addInterfaceMaterial(
170  _equilibrium_traction_calculator_name, unique_material_name, paramsm);
171 }
172 
173 void
175 {
176  // Enforce consistency
177  if (_ndisp != _mesh->dimension())
178  paramError("displacements", "Number of displacements must match problem dimension.");
179 
181 
182  if (_current_task == "add_interface_kernel")
184  else if (_current_task == "add_master_action_material")
186 
187  // optional, add required outputs
189 }
190 
191 void
193 {
195  addRelationshipManagers(input_rm_type, ips);
196 }
197 
198 void
199 CohesiveZoneAction::prepareSaveInInputs(std::vector<AuxVariableName> & save_in_names,
200  std::string & save_in_side,
201  const std::vector<AuxVariableName> & var_name_master,
202  const std::vector<AuxVariableName> & var_name_slave,
203  const int & i) const
204 {
205  save_in_names.clear();
206  save_in_side.clear();
207  if (var_name_master.size() == _ndisp)
208  {
209  save_in_names.push_back(var_name_master[i]);
210  save_in_side += "m";
211  if (var_name_slave.size() == _ndisp)
212  save_in_side += " ";
213  }
214  if (var_name_slave.size() == _ndisp)
215  {
216  save_in_names.push_back(var_name_slave[i]);
217  save_in_side += "s";
218  }
219 }
220 
221 void
223 {
224  // Ensure material output order and family vectors are same size as generate output
225 
226  // check number of supplied orders and families
228  paramError("material_output_order",
229  "The number of orders assigned to material outputs must be: 0 to be assigned "
230  "CONSTANT; 1 to assign all outputs the same value, or the same size as the number "
231  "of generate outputs listed.");
232 
233  if (_material_output_family.size() > 1 &&
235  paramError("material_output_family",
236  "The number of families assigned to material outputs must be: 0 to be assigned "
237  "MONOMIAL; 1 to assign all outputs the same value, or the same size as the number "
238  "of generate outputs listed.");
239 
240  // if no value was provided, chose the default CONSTANT
241  if (_material_output_order.size() == 0)
243 
244  // For only one order, make all orders the same magnitude
245  if (_material_output_order.size() == 1)
247  std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
248 
249  if (_verbose)
250  Moose::out << COLOR_CYAN << "*** Automatic applied material output orders ***"
251  << "\n"
252  << _name << ": " << Moose::stringify(_material_output_order) << "\n"
253  << COLOR_DEFAULT;
254 
255  // if no value was provided, chose the default MONOMIAL
256  if (_material_output_family.size() == 0)
258 
259  // For only one family, make all families that value
260  if (_material_output_family.size() == 1)
262  std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
263 
264  if (_verbose)
265  Moose::out << COLOR_CYAN << "*** Automatic applied material output families ***"
266  << "\n"
267  << _name << ": " << Moose::stringify(_material_output_family) << "\n"
268  << COLOR_DEFAULT;
269 }
270 
271 void
273 {
274  if (_current_task == "add_material")
276 
277  // Add variables (optional)
278  if (_current_task == "add_aux_variable")
279  {
280  unsigned int index = 0;
281  for (auto out : _generate_output)
282  {
283  const auto & order = _material_output_order[index];
284  const auto & family = _material_output_family[index];
285 
286  std::string type = (order == "CONSTANT" && family == "MONOMIAL")
287  ? "MooseVariableConstMonomial"
288  : "MooseVariable";
289 
290  // Create output helper aux variables
291  auto params = _factory.getValidParams(type);
292  params.set<MooseEnum>("order") = order;
293  params.set<MooseEnum>("family") = family;
294  if (family == "MONOMIAL")
295  _problem->addAuxVariable(type, addBaseName(out), params);
296  else
297  _problem->addVariable(type, addBaseName(out), params);
298 
299  index++;
300  }
301  }
302 
303  // Add output AuxKernels
304  else if (_current_task == "add_aux_kernel")
305  {
306  const std::string material_output_aux_name = _use_AD ? "ADMaterialRealAux" : "MaterialRealAux";
307  // Loop through output aux variables
308  unsigned int index = 0;
309  for (auto out : _generate_output)
310  {
311  if (_material_output_family[index] == "MONOMIAL")
312  {
313  InputParameters params = _factory.getValidParams(material_output_aux_name);
314  params.set<MaterialPropertyName>("property") = addBaseName(out);
315  params.set<AuxVariableName>("variable") = addBaseName(out);
316  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
317  params.set<std::vector<BoundaryName>>("boundary") = _boundary;
318  params.set<bool>("check_boundary_restricted") = false;
319  _problem->addAuxKernel(material_output_aux_name, addBaseName(out) + '_' + name(), params);
320  }
321  index++;
322  }
323  }
324 }
325 
326 void
328 {
329  if (_current_task == "add_material")
330  {
331  // Add output Materials
332  for (auto out : _generate_output)
333  {
335 
336  // RealVectorCartesianComponent
337  if (
338  [&]()
339  {
340  for (const auto & vq : _real_vector_cartesian_component_table)
341  for (unsigned int a = 0; a < 3; ++a)
342  if (vq.first + '_' + _component_table[a] == out)
343  {
344  auto type = _use_AD ? "ADCZMRealVectorCartesianComponent"
345  : "CZMRealVectorCartesianComponent";
346  params = _factory.getValidParams(type);
347  params.set<std::string>("real_vector_value") = vq.second;
348  params.set<unsigned int>("index") = a;
349  params.set<std::vector<BoundaryName>>("boundary") = _boundary;
350  params.set<MaterialPropertyName>("property_name") = addBaseName(out);
351  params.set<std::string>("base_name") = _base_name;
352  _problem->addInterfaceMaterial(type, addBaseName(out) + '_' + name(), params);
353  return true;
354  }
355  return false;
356  }())
357  continue;
358 
359  // CZMRealVectorScalar
360  if (setupOutput(out,
362  [&](std::string prop_name, std::string direction)
363  {
364  auto type = _use_AD ? "ADCZMRealVectorScalar" : "CZMRealVectorScalar";
365  params = _factory.getValidParams(type);
366  params.set<std::string>("real_vector_value") = prop_name;
367  params.set<MooseEnum>("direction") = direction;
368  params.set<MaterialPropertyName>("property_name") = addBaseName(out);
369  params.set<std::vector<BoundaryName>>("boundary") = _boundary;
370  params.set<std::string>("base_name") = _base_name;
371  _problem->addInterfaceMaterial(
372  type, addBaseName(out) + '_' + name(), params);
373  }))
374  continue;
375 
376  mooseError("CZM Master: unable to add output Material");
377  }
378  }
379 }
380 
381 void
383 {
384 
385  // Gather info about all other master actions when we add variables
386  if (_current_task == "validate_coordinate_systems")
387  {
388  auto actions = _awh.getActions<CohesiveZoneAction>();
389  for (const auto & action : actions)
390  {
391  const auto size_before = _boundary_name_union.size();
392  const auto added_size = action->_boundary.size();
393  _boundary_name_union.insert(action->_boundary.begin(), action->_boundary.end());
394  const auto size_after = _boundary_name_union.size();
395  if (size_after != size_before + added_size)
396  mooseError("The boundary restrictions in the CohesiveZoneAction actions must be "
397  "non-overlapping.");
398  }
399 
400  for (const auto & action : actions)
401  {
402  // check for different strain definitions
403  _strain_formulation_union.insert(action->_strain);
404  const auto size_after = _strain_formulation_union.size();
405 
406  if (size_after != 1)
407  mooseError("All blocks of the CohesiveZoneAction should have the same strain formulation");
408  }
409  }
410 }
std::vector< AuxVariableName > _diag_save_in_master
std::string _equilibrium_traction_calculator_name
static InputParameters validParams()
RelationshipManagerType
ActionWarehouse & _awh
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)
std::vector< AuxVariableName > _save_in_master
residual debugging
Strain
strain formulation
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
const ExecFlagType EXEC_TIMESTEP_END
virtual const std::string & name() const
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.
Factory & _factory
std::vector< AuxVariableName > _diag_save_in_slave
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()
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
void paramError(const std::string &param, Args... args) const
std::string stringify(const T &t)
const std::string _name
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
std::vector< AuxVariableName > _save_in_slave
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)