https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
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
92void
104
105void
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()) ||
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
125 mooseError("stress_vectorpostprocessor should have the same number of crack front points as "
126 "CrackFrontDefinition.",
127 "\n stress_vectorpostprocessor size = ",
128 _stress_vpp->size(),
129 "\n cracktips in MeshCut2DFractureUserObject = ",
131
133 mooseError("k_critical_vectorpostprocessor must have the same number of crack front points as "
134 "CrackFrontDefinition.",
135 "\n k_critical_vectorpostprocessor size = ",
136 _k_critical_vpp->size(),
137 "\n cracktips in MeshCut2DFractureUserObject = ",
139
141 for (unsigned int i = 0; i < _original_and_current_front_node_ids.size(); ++i)
142 {
143 // only extend crack with kcrit or nonlocal stress, never both.
144 bool was_crack_extended_kcrit = false;
145 if (_use_k)
146 {
147 Real k_crit = _k_critical;
148 if (_k_critical_vpp)
149 k_crit = std::min(_k_critical_vpp->at(i), _k_critical);
150
151 Real k_squared = _ki_vpp->at(i) * _ki_vpp->at(i) + _kii_vpp->at(i) * _kii_vpp->at(i);
152 if (k_squared > (k_crit * k_crit) && _ki_vpp->at(i) > 0)
153 {
154 // growth direction in crack front coord (cfc) system based on the max hoop stress criterion
155 // Jiang, Wen, Benjamin W.Spencer, and John E.Dolbow.
156 // "Ceramic nuclear fuel fracture modeling with the extended finite "
157 // "element method." Engineering Fracture Mechanics 223(2020):106713.
158 // https://doi.org/10.1016/j.engfracmech.2019.106713
159 // Equation 6
160 Real ki = _ki_vpp->at(i);
161 Real kii = _kii_vpp->at(i);
162 Real sqrt_k = std::sqrt(ki * ki + 8 * kii * kii);
163
164 Real theta_m = 0;
165 Real theta_p = 0;
166 if (std::abs(kii) > libMesh::TOLERANCE)
167 {
168 theta_m = 2 * std::atan((ki - sqrt_k) / (4 * kii));
169 theta_p = 2 * std::atan((ki + sqrt_k) / (4 * kii));
170 }
171
172 // Equation 5 check relative sigma_tt
173 Real sigma_tt_m = ki * (3 * std::cos(theta_m / 2) + std::cos(3 * theta_m / 2)) +
174 kii * (-3 * std::sin(theta_m / 2) - 3 * std::sin(3 * theta_m / 2));
175 Real sigma_tt_p = ki * (3 * std::cos(theta_p / 2) + std::cos(3 * theta_p / 2)) +
176 kii * (-3 * std::sin(theta_p / 2) - 3 * std::sin(3 * theta_p / 2));
177 Real theta;
178 if (sigma_tt_m > sigma_tt_p)
179 theta = theta_m;
180 else
181 theta = theta_p;
182
183 RealVectorValue dir_cfc;
184 dir_cfc(0) = std::cos(theta);
185 dir_cfc(1) = std::sin(theta);
186 dir_cfc(2) = 0;
187
188 // growth direction in global coord system based on the max hoop stress criterion
189 RealVectorValue dir_global =
191 Point dir_global_pt(dir_global(0), dir_global(1), dir_global(2));
192 Point nodal_offset = dir_global_pt * _growth_increment;
194 std::make_pair(_original_and_current_front_node_ids[i].second, nodal_offset));
195 }
196 }
197 if (_use_stress && !was_crack_extended_kcrit && _stress_vpp->at(i) > _stress_threshold)
198 {
199 // crack will only be extended if it was not already extended by kcrit
200 // just extending the crack in the same direction it was going
201 RealVectorValue dir_cfc(1.0, 0.0, 0.0);
202 RealVectorValue dir_global =
204 Point dir_global_pt(dir_global(0), dir_global(1), dir_global(2));
205 Point nodal_offset = dir_global_pt * _growth_increment;
207 std::make_pair(_original_and_current_front_node_ids[i].second, nodal_offset));
208 }
209 }
210}
registerMooseObject("XFEMApp", MeshCut2DFractureUserObject)
void updateNumberOfCrackFrontPoints(const std::size_t num_points)
Change the number of crack front nodes.
void isCutterModified(const bool is_cutter_modified)
Set the value of _is_cutter_modified.
RealVectorValue rotateFromCrackFrontCoordsToGlobal(const RealVectorValue vector, const std::size_t point_index) const
Rotate a vector from crack front cartesian coordinate to global cartesian coordinate.
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
MeshCut2DFractureUserObject: (1) reads in a mesh describing the crack surface (2) uses the mesh to do...
const Real _stress_threshold
Maximum stress criterion threshold for crack growth.
const bool _use_stress
is stress used to grow crack
const Real _k_critical
critical k value for crack growth
const std::vector< Real > *const _kii_vpp
Pointer fracture integral kii if available.
const std::vector< Real > *const _k_critical_vpp
Pointer to crack front critical k if available.
const bool _use_k
are fracture integrals used for growing crack
const Real & _growth_increment
amount to grow crack by for each xfem update step
const std::vector< Real > *const _stress_vpp
Pointer to crack front stress if available.
const std::vector< Real > *const _ki_vpp
Pointer fracture integral ki if available.
virtual void findActiveBoundaryGrowth() override
Find growth direction at each active node.
MeshCut2DFractureUserObject(const InputParameters &parameters)
MeshCut2DUserObjectBase: (1) reads in a mesh describing the crack surface, (2) Fills xfem cut element...
void addNucleatedCracksToMesh()
Calls into MeshCutNucleation UO to add cracks.
void growFront()
grow the cutter mesh
static InputParameters validParams()
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...
std::vector< std::pair< dof_id_type, Point > > _active_front_node_growth_vectors
contains the active node ids and their growth vectors
bool _is_mesh_modified
Indicator that shows if the cutting mesh is modified or not in this calculation step.
CrackFrontDefinition * _crack_front_definition
user object for communicating between solid_mechanics interaction integrals and xfem cutter mesh
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
static constexpr Real TOLERANCE