https://mooseframework.inl.gov
MeshCut2DFractureUserObject.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 
11 
12 #include "XFEMFuncs.h"
13 #include "MooseError.h"
14 #include "MooseMesh.h"
15 #include "libmesh/edge_edge2.h"
16 #include "libmesh/serial_mesh.h"
17 #include "libmesh/mesh_tools.h"
18 #include "algorithm"
19 
20 #include "CrackFrontDefinition.h"
21 
23 
26 {
28  params.addClassDescription("XFEM mesh cutter for 2D models that defines cuts with a"
29  "mesh and uses fracture integrals to determine growth");
30  params.addRequiredParam<Real>("growth_increment",
31  "Length to grow crack if k>k_critical or stress>stress_threshold");
32  params.addParam<Real>("k_critical", "Critical fracture toughness.");
33  params.addParam<Real>("stress_threshold", "Stress threshold for growing crack");
34  params.addParam<VectorPostprocessorName>(
35  "ki_vectorpostprocessor", "II_KI_1", "The name of the vectorpostprocessor that contains KI");
36  params.addParam<VectorPostprocessorName>("kii_vectorpostprocessor",
37  "II_KII_1",
38  "The name of the vectorpostprocessor that contains KII");
39  params.addParam<VectorPostprocessorName>(
40  "stress_vectorpostprocessor",
41  "The name of the vectorpostprocessor that contains crack front stress");
42  params.addParam<std::string>("stress_vector_name",
43  "crack_tip_stress",
44  "The name of the stress vector in the stress_vectorpostprocessor");
45  params.addParam<VectorPostprocessorName>(
46  "k_critical_vectorpostprocessor",
47  "The name of the vectorpostprocessor that contains critical fracture toughness at crack tip");
48  params.addParam<std::string>(
49  "k_critical_vector_name",
50  "The name of the k_critical vector in the k_critical_vectorpostprocessor");
51  return params;
52 }
53 
55  : MeshCut2DUserObjectBase(parameters),
56  _growth_increment(getParam<Real>("growth_increment")),
57  _use_k(isParamValid("k_critical") || isParamValid("k_critical_vectorpostprocessor")),
58  _use_stress(isParamValid("stress_threshold")),
59  _k_critical(isParamValid("k_critical") ? getParam<Real>("k_critical")
60  : std::numeric_limits<Real>::max()),
61  _stress_threshold(_use_stress ? getParam<Real>("stress_threshold")
62  : std::numeric_limits<Real>::max()),
63  _ki_vpp(_use_k ? &getVectorPostprocessorValue(
64  "ki_vectorpostprocessor",
65  getParam<VectorPostprocessorName>("ki_vectorpostprocessor"))
66  : nullptr),
67  _kii_vpp(_use_k ? &getVectorPostprocessorValue(
68  "kii_vectorpostprocessor",
69  getParam<VectorPostprocessorName>("kii_vectorpostprocessor"))
70  : nullptr),
71  _stress_vpp(_use_stress
72  ? &getVectorPostprocessorValue("stress_vectorpostprocessor",
73  getParam<std::string>("stress_vector_name"))
74  : nullptr),
75  _k_critical_vpp(
76  isParamValid("k_critical_vectorpostprocessor")
77  ? &getVectorPostprocessorValue("k_critical_vectorpostprocessor",
78  getParam<std::string>("k_critical_vector_name"))
79  : nullptr)
80 {
81  if (!_use_k && !_use_stress)
82  paramError("k_critical",
83  "Must set crack extension criterion with k_critical, k_critical_vectorpostprocessor "
84  "or stress_threshold.");
85 
86  if (isParamValid("k_critical") && isParamValid("k_critical_vectorpostprocessor"))
87  paramError("k_critical",
88  "Fracture toughness cannot be specified by both k_critical and "
89  "k_critical_vectorpostprocessor.");
90 }
91 
92 void
94 {
95  _is_mesh_modified = false;
97  growFront();
99  // update _crack_front_definition with nucleated nodes
103 }
104 
105 void
107 {
108  // The k*_vpp & stress_vpp are empty (but not a nullptr) on the very first time step because this
109  // UO is called before the InteractionIntegral or crackFrontStress vpp
110  if ((!_ki_vpp || _ki_vpp->size() == 0) && (!_stress_vpp || _stress_vpp->size() == 0))
111  return;
112 
113  if (_use_k && ((_ki_vpp->size() != _kii_vpp->size()) ||
114  (_ki_vpp->size() != _original_and_current_front_node_ids.size())))
115  mooseError("ki_vectorpostprocessor and kii_vectorpostprocessor should have the same number of "
116  "crack tips as CrackFrontDefinition.",
117  "\n ki size = ",
118  _ki_vpp->size(),
119  "\n kii size = ",
120  _kii_vpp->size(),
121  "\n cracktips in MeshCut2DFractureUserObject = ",
123 
124  if (_use_stress && ((_stress_vpp->size() != _original_and_current_front_node_ids.size())))
125  mooseError("stress_vectorpostprocessor should have the same number of crack front points as "
126  "CrackFrontDefinition. If it is empty, check that CrackFrontNonlocalStress "
127  "vectorpostprocess has execute_on = TIMESTEP_BEGIN",
128  "\n stress_vectorpostprocessor size = ",
129  _stress_vpp->size(),
130  "\n cracktips in MeshCut2DFractureUserObject = ",
132 
134  mooseError("k_critical_vectorpostprocessor must have the same number of crack front points as "
135  "CrackFrontDefinition.",
136  "\n k_critical_vectorpostprocessor size = ",
137  _k_critical_vpp->size(),
138  "\n cracktips in MeshCut2DFractureUserObject = ",
140 
142  for (unsigned int i = 0; i < _original_and_current_front_node_ids.size(); ++i)
143  {
144  if (_use_k)
145  {
146  Real k_crit = _k_critical;
147  if (_k_critical_vpp)
148  k_crit = std::min(_k_critical_vpp->at(i), _k_critical);
149  Real k_squared = _ki_vpp->at(i) * _ki_vpp->at(i) + _kii_vpp->at(i) * _kii_vpp->at(i);
150  if (k_squared > (k_crit * k_crit) && _ki_vpp->at(i) > 0)
151  {
152  // growth direction in crack front coord (cfc) system based on the max hoop stress
153  // criterion
154  Real ki = _ki_vpp->at(i);
155  Real kii = _kii_vpp->at(i);
156  Real sqrt_k = std::sqrt(ki * ki + kii * kii);
157  Real theta = 2 * std::atan((ki - sqrt_k) / (4 * kii));
158  RealVectorValue dir_cfc;
159  dir_cfc(0) = std::cos(theta);
160  dir_cfc(1) = std::sin(theta);
161  dir_cfc(2) = 0;
162 
163  // growth direction in global coord system based on the max hoop stress criterion
164  RealVectorValue dir_global =
166  Point dir_global_pt(dir_global(0), dir_global(1), dir_global(2));
167  Point nodal_offset = dir_global_pt * _growth_increment;
169  std::make_pair(_original_and_current_front_node_ids[i].second, nodal_offset));
170  }
171  }
172  else if (_use_stress && _stress_vpp->at(i) > _stress_threshold)
173  {
174  // just extending the crack in the same direction it was going
175  RealVectorValue dir_cfc(1.0, 0.0, 0.0);
176  RealVectorValue dir_global =
178  Point dir_global_pt(dir_global(0), dir_global(1), dir_global(2));
179  Point nodal_offset = dir_global_pt * _growth_increment;
181  std::make_pair(_original_and_current_front_node_ids[i].second, nodal_offset));
182  }
183  }
184 }
void isCutterModified(const bool is_cutter_modified)
Set the value of _is_cutter_modified.
MeshCut2DFractureUserObject(const InputParameters &parameters)
const std::vector< Real > *const _kii_vpp
Pointer fracture integral kii if available.
const Real & _growth_increment
amount to grow crack by for each xfem update step
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const bool _use_k
are fracture integrals used for growing crack
virtual void findActiveBoundaryGrowth() override
Find growth direction at each active node
static InputParameters validParams()
const std::vector< Real > *const _stress_vpp
Pointer to crack front stress if available.
std::vector< std::pair< dof_id_type, dof_id_type > > _original_and_current_front_node_ids
This vector of pairs orders crack tips to make the order used in this class the same as those for the...
void addRequiredParam(const std::string &name, const std::string &doc_string)
void updateNumberOfCrackFrontPoints(const std::size_t num_points)
Change the number of crack front nodes.
auto max(const L &left, const R &right)
registerMooseObject("XFEMApp", MeshCut2DFractureUserObject)
bool isParamValid(const std::string &name) const
RealVectorValue rotateFromCrackFrontCoordsToGlobal(const RealVectorValue vector, const std::size_t point_index) const
Rotate a vector from crack front cartesian coordinate to global cartesian coordinate.
static InputParameters validParams()
MeshCut2DUserObjectBase: (1) reads in a mesh describing the crack surface, (2) Fills xfem cut element...
void paramError(const std::string &param, Args... args) const
MeshCut2DFractureUserObject: (1) reads in a mesh describing the crack surface (2) uses the mesh to do...
const bool _use_stress
is stress used to grow crack
void addNucleatedCracksToMesh()
Calls into MeshCutNucleation UO to add cracks.
const std::vector< Real > *const _ki_vpp
Pointer fracture integral ki if available.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Real _stress_threshold
Maximum stress criterion threshold for crack growth.
bool _is_mesh_modified
Indicator that shows if the cutting mesh is modified or not in this calculation step.
void mooseError(Args &&... args) const
const std::vector< Real > *const _k_critical_vpp
Pointer to crack front critical k if available.
void addClassDescription(const std::string &doc_string)
void growFront()
grow the cutter mesh
const Real _k_critical
critical k value for crack growth
std::vector< std::pair< dof_id_type, Point > > _active_front_node_growth_vectors
contains the active node ids and their growth vectors
CrackFrontDefinition * _crack_front_definition
user object for communicating between solid_mechanics interaction integrals and xfem cutter mesh ...