https://mooseframework.inl.gov
Loading...
Searching...
No Matches
JIntegral.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 "JIntegral.h"
11#include "RankTwoTensor.h"
12#include "Conversion.h"
13#include "libmesh/string_to_enum.h"
14#include "libmesh/quadrature.h"
15#include "libmesh/utility.h"
17registerMooseObject("SolidMechanicsApp", JIntegral);
18
21{
24 "displacements",
25 "The displacements appropriate for the simulation geometry and coordinate system");
26 params.addRequiredParam<UserObjectName>("crack_front_definition",
27 "The CrackFrontDefinition user object name");
28 MooseEnum position_type("Angle Distance", "Distance");
29 params.addParam<MooseEnum>(
30 "position_type",
31 position_type,
32 "The method used to calculate position along crack front. Options are: " +
33 position_type.getRawNames());
34 MooseEnum integral_vec("JIntegral CIntegral KFromJIntegral", "JIntegral");
35 params.addRequiredParam<MooseEnum>("integral",
36 integral_vec,
37 "Domain integrals to calculate. Choices are: " +
38 integral_vec.getRawNames());
39 params.addParam<unsigned int>("symmetry_plane",
40 "Account for a symmetry plane passing through "
41 "the plane of the crack, normal to the specified "
42 "axis (0=x, 1=y, 2=z)");
43 params.addParam<Real>("poissons_ratio", "Poisson's ratio");
44 params.addParam<Real>("youngs_modulus", "Young's modulus of the material.");
45 params.set<bool>("use_displaced_mesh") = false;
46 params.addRequiredParam<unsigned int>("ring_index", "Ring ID");
47 MooseEnum q_function_type("Geometry Topology", "Geometry");
48 params.addParam<MooseEnum>("q_function_type",
49 q_function_type,
50 "The method used to define the integration domain. Options are: " +
51 q_function_type.getRawNames());
52 params.addClassDescription("Computes the J-Integral, a measure of the strain energy release rate "
53 "at a crack tip, which can be used as a criterion for fracture "
54 "growth. It can, alternatively, compute the C(t) integral");
55 return params;
56}
57
59 : ElementVectorPostprocessor(parameters),
60 _crack_front_definition(&getUserObject<CrackFrontDefinition>("crack_front_definition")),
61 _integral(getParam<MooseEnum>("integral").getEnum<IntegralType>()),
62 _J_thermal_term_vec(hasMaterialProperty<RealVectorValue>("J_thermal_term_vec")
63 ? &getMaterialProperty<RealVectorValue>("J_thermal_term_vec")
64 : nullptr),
65 _Eshelby_tensor(_integral != IntegralType::CIntegral
66 ? &getMaterialProperty<RankTwoTensor>("Eshelby_tensor")
67 : nullptr),
68 _Eshelby_tensor_dissipation(
69 _integral == IntegralType::CIntegral
70 ? &getMaterialProperty<RankTwoTensor>("Eshelby_tensor_dissipation")
71 : nullptr),
72 _fe_vars(getCoupledMooseVars()),
73 _fe_type(_fe_vars[0]->feType()),
74 _has_symmetry_plane(isParamValid("symmetry_plane")),
75 _poissons_ratio(isParamValid("poissons_ratio") ? getParam<Real>("poissons_ratio") : 0),
76 _youngs_modulus(isParamValid("youngs_modulus") ? getParam<Real>("youngs_modulus") : 0),
77 _ring_index(getParam<unsigned int>("ring_index")),
78 _q_function_type(getParam<MooseEnum>("q_function_type").getEnum<QMethod>()),
79 _position_type(getParam<MooseEnum>("position_type").getEnum<PositionType>()),
80 _x(declareVector("x")),
81 _y(declareVector("y")),
82 _z(declareVector("z")),
83 _position(declareVector("id")),
84 _j_integral(declareVector((_integral == IntegralType::KFromJIntegral
85 ? "K_"
86 : (_integral == IntegralType::JIntegral ? "J_" : "C_")) +
87 Moose::stringify(_ring_index)))
88{
89}
90
91void
93{
97 (!isParamValid("youngs_modulus") || !isParamValid("poissons_ratio")))
98 mooseError("youngs_modulus and poissons_ratio must be specified if integrals = KFromJIntegral");
99}
100
101void
103{
104 std::size_t num_pts;
105 if (_treat_as_2d && _using_mesh_cutter == false)
106 num_pts = 1;
107 else
109
110 _x.assign(num_pts, 0.0);
111 _y.assign(num_pts, 0.0);
112 _z.assign(num_pts, 0.0);
113 _position.assign(num_pts, 0.0);
114 _j_integral.assign(num_pts, 0.0);
115
116 for (const auto * fe_var : _fe_vars)
117 {
118 if (fe_var->feType() != _fe_type)
119 mooseError("displacements", "All coupled displacements must have the same type");
120 }
121}
122
123Real
124JIntegral::computeQpIntegral(const std::size_t crack_front_point_index,
125 const Real scalar_q,
126 const RealVectorValue & grad_of_scalar_q)
127{
128 RankTwoTensor grad_of_vector_q;
129 const RealVectorValue & crack_direction =
130 _crack_front_definition->getCrackDirection(crack_front_point_index);
131 grad_of_vector_q(0, 0) = crack_direction(0) * grad_of_scalar_q(0);
132 grad_of_vector_q(0, 1) = crack_direction(0) * grad_of_scalar_q(1);
133 grad_of_vector_q(0, 2) = crack_direction(0) * grad_of_scalar_q(2);
134 grad_of_vector_q(1, 0) = crack_direction(1) * grad_of_scalar_q(0);
135 grad_of_vector_q(1, 1) = crack_direction(1) * grad_of_scalar_q(1);
136 grad_of_vector_q(1, 2) = crack_direction(1) * grad_of_scalar_q(2);
137 grad_of_vector_q(2, 0) = crack_direction(2) * grad_of_scalar_q(0);
138 grad_of_vector_q(2, 1) = crack_direction(2) * grad_of_scalar_q(1);
139 grad_of_vector_q(2, 2) = crack_direction(2) * grad_of_scalar_q(2);
140
141 Real eq;
142
144 eq = (*_Eshelby_tensor)[_qp].doubleContraction(grad_of_vector_q);
145 else
146 eq = (*_Eshelby_tensor_dissipation)[_qp].doubleContraction(grad_of_vector_q);
147
148 // Thermal component
149 Real eq_thermal = 0.0;
151 {
152 for (std::size_t i = 0; i < 3; i++)
153 eq_thermal += crack_direction(i) * scalar_q * (*_J_thermal_term_vec)[_qp](i);
154 }
155
156 Real q_avg_seg = 1.0;
158 {
159 q_avg_seg =
162 2.0;
163 }
164
165 Real etot = -eq + eq_thermal;
166
167 return etot / q_avg_seg;
168}
169
170void
172{
173 // calculate phi and dphi for this element
174 const std::size_t dim = _current_elem->dim();
175 std::unique_ptr<libMesh::FEBase> fe(libMesh::FEBase::build(dim, _fe_type));
176 fe->attach_quadrature_rule(const_cast<QBase *>(_qrule));
177 _phi_curr_elem = &fe->get_phi();
178 _dphi_curr_elem = &fe->get_dphi();
179 fe->reinit(_current_elem);
180
181 // calculate q for all nodes in this element
182 std::size_t ring_base = (_q_function_type == QMethod::Topology) ? 0 : 1;
183
184 for (std::size_t icfp = 0; icfp < _j_integral.size(); icfp++)
185 {
186 _q_curr_elem.clear();
187 for (std::size_t i = 0; i < _current_elem->n_nodes(); ++i)
188 {
189 const Node * this_node = _current_elem->node_ptr(i);
190 Real q_this_node;
191
194 icfp, _ring_index - ring_base, this_node);
195 else // QMethod::Topology
197 icfp, _ring_index - ring_base, this_node);
198
199 _q_curr_elem.push_back(q_this_node);
200 }
201
202 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
203 {
204 Real scalar_q = 0.0;
205 RealVectorValue grad_of_scalar_q(0.0, 0.0, 0.0);
206
207 for (std::size_t i = 0; i < _current_elem->n_nodes(); ++i)
208 {
209 scalar_q += (*_phi_curr_elem)[i][_qp] * _q_curr_elem[i];
210
211 for (std::size_t j = 0; j < _current_elem->dim(); ++j)
212 grad_of_scalar_q(j) += (*_dphi_curr_elem)[i][_qp](j) * _q_curr_elem[i];
213 }
214
215 _j_integral[icfp] +=
216 _JxW[_qp] * _coord[_qp] * computeQpIntegral(icfp, scalar_q, grad_of_scalar_q);
217 }
218 }
219}
220
221void
223{
225
226 for (std::size_t i = 0; i < _j_integral.size(); ++i)
227 {
229 _j_integral[i] *= 2.0;
230
231 Real sign = (_j_integral[i] > 0.0) ? 1.0 : ((_j_integral[i] < 0.0) ? -1.0 : 0.0);
232
234 _j_integral[i] = sign * std::sqrt(std::abs(_j_integral[i]) * _youngs_modulus /
235 (1.0 - Utility::pow<2>(_poissons_ratio)));
236
237 const auto cfp = _crack_front_definition->getCrackFrontPoint(i);
238 _x[i] = (*cfp)(0);
239 _y[i] = (*cfp)(1);
240 _z[i] = (*cfp)(2);
241
244 else
246 }
247}
248
249void
251{
252 const auto & uo = static_cast<const JIntegral &>(y);
253
254 for (auto i = beginIndex(_j_integral); i < _j_integral.size(); ++i)
255 _j_integral[i] += uo._j_integral[i];
256}
const std::vector< double > y
registerMooseObject("SolidMechanicsApp", JIntegral)
unsigned int dim
void ErrorVector unsigned int
Class used in fracture integrals to define geometric characteristics of the crack front.
const Point * getCrackFrontPoint(const std::size_t point_index) const
Get a Point object for a specified point on the crack front.
Real getCrackFrontBackwardSegmentLength(const std::size_t point_index) const
Get the length of the line segment on the crack front behind the specified position.
bool treatAs2D() const
Whether the fracture computations are treated as 2D for the model.
Real getCrackFrontForwardSegmentLength(const std::size_t point_index) const
Get the length of the line segment on the crack front ahead of the specified position.
Real DomainIntegralTopologicalQFunction(std::size_t crack_front_point_index, std::size_t ring_index, const Node *const current_node) const
Compute the q function for the case where it is defined through element connectivity.
Real getDistanceAlongFront(const std::size_t point_index) const
Get the distance along the crack front from the beginning of the crack to the specified position.
std::size_t getNumCrackFrontPoints() const
Get the number of points defining the crack front as a set of line segments.
bool usingMeshCutter() const
Is the crack defined by a mesh cutter object.
Real getAngleAlongFront(const std::size_t point_index) const
Get the angle along the crack front from the beginning of the crack to the specified position.
const RealVectorValue & getCrackDirection(const std::size_t point_index) const
Get the unit vector of the crack extension direction at the specified position.
Real DomainIntegralQFunction(std::size_t crack_front_point_index, std::size_t ring_index, const Node *const current_node) const
Compute the q function for the case where it is defined geometrically.
const QBase *const & _qrule
const Elem *const & _current_elem
const MooseArray< Real > & _coord
const MooseArray< Real > & _JxW
static InputParameters validParams()
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
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)
T & set(const std::string &name, bool quiet_mode=false)
This vectorpostprocessor computes the J-Integral, which is a measure of the strain energy release rat...
Definition JIntegral.h:22
const CrackFrontDefinition *const _crack_front_definition
Definition JIntegral.h:47
virtual void execute() override
Definition JIntegral.C:171
std::vector< Real > _q_curr_elem
Vector of q function values for the nodes in the current element.
Definition JIntegral.h:84
virtual void threadJoin(const UserObject &y) override
Definition JIntegral.C:250
QMethod
Enum used to select the method used to compute the q function used in the fracture integrals.
Definition JIntegral.h:77
enum JIntegral::IntegralType _integral
IntegralType
Enum defining the type of integral to be computed.
Definition JIntegral.h:49
VectorPostprocessorValue & _position
Definition JIntegral.h:98
Real _youngs_modulus
Young's modulus of the material.
Definition JIntegral.h:72
VectorPostprocessorValue & _z
Definition JIntegral.h:97
static InputParameters validParams()
Definition JIntegral.C:20
std::vector< MooseVariableFEBase * > _fe_vars
Vector of all coupled variables.
Definition JIntegral.h:64
VectorPostprocessorValue & _j_integral
Definition JIntegral.h:99
virtual void initialSetup() override
Definition JIntegral.C:92
enum JIntegral::QMethod _q_function_type
const MaterialProperty< RealVectorValue > *const _J_thermal_term_vec
Definition JIntegral.h:51
Real computeQpIntegral(const std::size_t crack_front_point_index, const Real scalar_q, const RealVectorValue &grad_of_scalar_q)
Compute the contribution of a specific quadrature point to the J integral for a point on the crack fr...
Definition JIntegral.C:124
const std::vector< std::vector< libMesh::RealGradient > > * _dphi_curr_elem
Vector of gradients of shape function values for the current element.
Definition JIntegral.h:88
bool _treat_as_2d
Whether to treat a 3D model as 2D for computation of fracture integrals.
Definition JIntegral.h:60
unsigned int _qp
Current quadrature point index.
Definition JIntegral.h:90
virtual void initialize() override
Definition JIntegral.C:102
bool _using_mesh_cutter
Whether the crack is defined by an XFEM cutter mesh.
Definition JIntegral.h:62
const std::vector< std::vector< Real > > * _phi_curr_elem
Vector of shape function values for the current element.
Definition JIntegral.h:86
PositionType
Enum used to define how the distance along the crack front is measured (angle or distance)
Definition JIntegral.h:81
VectorPostprocessorValue & _y
Definition JIntegral.h:96
std::size_t _ring_index
Index of the ring for the integral computed by this object.
Definition JIntegral.h:74
virtual void finalize() override
Definition JIntegral.C:222
VectorPostprocessorValue & _x
Vectors computed by this VectorPostprocessor: x,y,z coordinates, position of nodes along crack front,...
Definition JIntegral.h:95
Real _poissons_ratio
Poisson's ratio of the material.
Definition JIntegral.h:70
bool _has_symmetry_plane
Whether the crack plane is also a symmetry plane in the model.
Definition JIntegral.h:68
const libMesh::FEType & _fe_type
FEType object defining order and family of displacement variables.
Definition JIntegral.h:66
enum JIntegral::PositionType _position_type
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
std::unique_ptr< FEGenericBase< Real > > build(const unsigned int dim, const FEType &fet)