13 #include "RankTwoTensor.h"
14 #include "libmesh/string_to_enum.h"
15 #include "libmesh/quadrature.h"
25 params.addClassDescription(
"Calculates the J-integral at a specified point "
26 " along the crack front");
27 params.addRequiredParam<UserObjectName>(
"crack_front_definition",
28 "The CrackFrontDefinition user object name");
29 params.addParam<
unsigned int>(
30 "crack_front_point_index",
31 "The index of the point on the crack front corresponding to this q function");
32 params.addParam<
bool>(
33 "convert_J_to_K",
false,
"Convert J-integral to stress intensity factor K.");
34 params.addParam<
unsigned int>(
"symmetry_plane",
35 "Account for a symmetry plane passing through "
36 "the plane of the crack, normal to the specified "
37 "axis (0=x, 1=y, 2=z)");
38 params.addParam<Real>(
"poissons_ratio",
"Poisson's ratio");
39 params.addParam<Real>(
"youngs_modulus",
"Young's modulus of the material.");
40 params.set<
bool>(
"use_displaced_mesh") =
false;
41 params.addParam<
unsigned int>(
"ring_index",
"Ring ID");
42 params.addParam<
unsigned int>(
"ring_first",
"First Ring ID");
43 MooseEnum q_function_type(
"Geometry Topology",
"Geometry");
44 params.addParam<MooseEnum>(
"q_function_type",
46 "The method used to define the integration domain. Options are: " +
47 q_function_type.getRawNames());
52 : ElementIntegralPostprocessor(parameters),
54 _has_crack_front_point_index(isParamValid(
"crack_front_point_index")),
55 _crack_front_point_index(
56 _has_crack_front_point_index ? getParam<unsigned int>(
"crack_front_point_index") : 0),
58 _Eshelby_tensor(getMaterialProperty<
RankTwoTensor>(
"Eshelby_tensor")),
59 _J_thermal_term_vec(hasMaterialProperty<RealVectorValue>(
"J_thermal_term_vec")
60 ? &getMaterialProperty<RealVectorValue>(
"J_thermal_term_vec")
62 _convert_J_to_K(getParam<bool>(
"convert_J_to_K")),
63 _has_symmetry_plane(isParamValid(
"symmetry_plane")),
64 _poissons_ratio(isParamValid(
"poissons_ratio") ? getParam<Real>(
"poissons_ratio") : 0),
65 _youngs_modulus(isParamValid(
"youngs_modulus") ? getParam<Real>(
"youngs_modulus") : 0),
66 _ring_index(getParam<unsigned int>(
"ring_index")),
67 _q_function_type(getParam<MooseEnum>(
"q_function_type"))
78 if (
_convert_J_to_K && (!isParamValid(
"youngs_modulus") || !isParamValid(
"poissons_ratio")))
79 mooseError(
"youngs_modulus and poissons_ratio must be specified if convert_J_to_K = true");
86 RealVectorValue grad_of_scalar_q(0.0, 0.0, 0.0);
88 const std::vector<std::vector<Real>> & phi_curr_elem = *
_phi_curr_elem;
89 const std::vector<std::vector<RealGradient>> & dphi_curr_elem = *
_dphi_curr_elem;
91 for (
unsigned int i = 0; i < _current_elem->n_nodes(); ++i)
95 for (
unsigned int j = 0; j < _current_elem->dim(); ++j)
96 grad_of_scalar_q(j) += dphi_curr_elem[i][_qp](j) *
_q_curr_elem[i];
100 const RealVectorValue & crack_direction =
102 grad_of_vector_q(0, 0) = crack_direction(0) * grad_of_scalar_q(0);
103 grad_of_vector_q(0, 1) = crack_direction(0) * grad_of_scalar_q(1);
104 grad_of_vector_q(0, 2) = crack_direction(0) * grad_of_scalar_q(2);
105 grad_of_vector_q(1, 0) = crack_direction(1) * grad_of_scalar_q(0);
106 grad_of_vector_q(1, 1) = crack_direction(1) * grad_of_scalar_q(1);
107 grad_of_vector_q(1, 2) = crack_direction(1) * grad_of_scalar_q(2);
108 grad_of_vector_q(2, 0) = crack_direction(2) * grad_of_scalar_q(0);
109 grad_of_vector_q(2, 1) = crack_direction(2) * grad_of_scalar_q(1);
110 grad_of_vector_q(2, 2) = crack_direction(2) * grad_of_scalar_q(2);
115 Real eq_thermal = 0.0;
118 for (
unsigned int i = 0; i < 3; i++)
119 eq_thermal += crack_direction(i) * scalar_q * (*_J_thermal_term_vec)[_qp](i);
122 Real q_avg_seg = 1.0;
131 Real etot = -eq + eq_thermal;
133 return etot / q_avg_seg;
142 FEType fe_type(Utility::string_to_enum<Order>(
"first"),
143 Utility::string_to_enum<FEFamily>(
"lagrange"));
144 const unsigned int dim = _current_elem->dim();
145 std::unique_ptr<FEBase> fe(FEBase::build(dim, fe_type));
146 fe->attach_quadrature_rule(const_cast<QBase *>(_qrule));
149 fe->reinit(_current_elem);
155 for (
unsigned int i = 0; i < _current_elem->n_nodes(); ++i)
157 const Node * this_node = _current_elem->node_ptr(i);
170 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
178 gatherSum(_integral_value);
180 _integral_value *= 2.0;
182 Real sign = (_integral_value > 0.0) ? 1.0 : ((_integral_value < 0.0) ? -1.0 : 0.0);
184 _integral_value = sign * std::sqrt(std::abs(_integral_value) *
_youngs_modulus /
187 return _integral_value;