www.mooseframework.org
JIntegral.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 // This post processor calculates the J-Integral
11 //
12 #include "JIntegral.h"
13 #include "RankTwoTensor.h"
14 #include "libmesh/string_to_enum.h"
15 #include "libmesh/quadrature.h"
16 
17 registerMooseObject("TensorMechanicsApp", JIntegral);
18 
20 
21 InputParameters
23 {
24  InputParameters params = ElementIntegralPostprocessor::validParams();
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",
45  q_function_type,
46  "The method used to define the integration domain. Options are: " +
47  q_function_type.getRawNames());
48  return params;
49 }
50 
51 JIntegral::JIntegral(const InputParameters & parameters)
52  : ElementIntegralPostprocessor(parameters),
53  _crack_front_definition(&getUserObject<CrackFrontDefinition>("crack_front_definition")),
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),
57  _treat_as_2d(false),
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")
61  : NULL),
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"))
68 {
69  if (_q_function_type == "TOPOLOGY")
70  _ring_first = getParam<unsigned int>("ring_first");
71 }
72 
73 void
75 {
77 
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");
80 }
81 
82 Real
84 {
85  Real scalar_q = 0.0;
86  RealVectorValue grad_of_scalar_q(0.0, 0.0, 0.0);
87 
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;
90 
91  for (unsigned int i = 0; i < _current_elem->n_nodes(); ++i)
92  {
93  scalar_q += phi_curr_elem[i][_qp] * _q_curr_elem[i];
94 
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];
97  }
98 
99  RankTwoTensor grad_of_vector_q;
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);
111 
112  Real eq = _Eshelby_tensor[_qp].doubleContraction(grad_of_vector_q);
113 
114  // Thermal component
115  Real eq_thermal = 0.0;
117  {
118  for (unsigned int i = 0; i < 3; i++)
119  eq_thermal += crack_direction(i) * scalar_q * (*_J_thermal_term_vec)[_qp](i);
120  }
121 
122  Real q_avg_seg = 1.0;
124  {
125  q_avg_seg =
128  2.0;
129  }
130 
131  Real etot = -eq + eq_thermal;
132 
133  return etot / q_avg_seg;
134 }
135 
136 Real
138 {
139  Real sum = 0;
140 
141  // calculate phi and dphi for this element
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));
147  _phi_curr_elem = &fe->get_phi();
148  _dphi_curr_elem = &fe->get_dphi();
149  fe->reinit(_current_elem);
150 
151  // calculate q for all nodes in this element
152  _q_curr_elem.clear();
153  unsigned int ring_base = (_q_function_type == "TOPOLOGY") ? 0 : 1;
154 
155  for (unsigned int i = 0; i < _current_elem->n_nodes(); ++i)
156  {
157  const Node * this_node = _current_elem->node_ptr(i);
158  Real q_this_node;
159 
160  if (_q_function_type == "GEOMETRY")
162  _crack_front_point_index, _ring_index - ring_base, this_node);
163  else if (_q_function_type == "TOPOLOGY")
165  _crack_front_point_index, _ring_index - ring_base, this_node);
166 
167  _q_curr_elem.push_back(q_this_node);
168  }
169 
170  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
171  sum += _JxW[_qp] * _coord[_qp] * computeQpIntegral();
172  return sum;
173 }
174 
175 Real
177 {
178  gatherSum(_integral_value);
180  _integral_value *= 2.0;
181 
182  Real sign = (_integral_value > 0.0) ? 1.0 : ((_integral_value < 0.0) ? -1.0 : 0.0);
183  if (_convert_J_to_K)
184  _integral_value = sign * std::sqrt(std::abs(_integral_value) * _youngs_modulus /
185  (1 - std::pow(_poissons_ratio, 2)));
186 
187  return _integral_value;
188 }
JIntegral::_ring_first
unsigned int _ring_first
Definition: JIntegral.h:51
JIntegral::_treat_as_2d
bool _treat_as_2d
Definition: JIntegral.h:43
pow
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
Definition: ExpressionBuilder.h:673
JIntegral::_crack_front_definition
const CrackFrontDefinition *const _crack_front_definition
Definition: JIntegral.h:40
JIntegral::_crack_front_point_index
const unsigned int _crack_front_point_index
Definition: JIntegral.h:42
JIntegral::_poissons_ratio
Real _poissons_ratio
Definition: JIntegral.h:48
CrackFrontDefinition::DomainIntegralQFunction
Real DomainIntegralQFunction(unsigned int crack_front_point_index, unsigned int ring_index, const Node *const current_node) const
Definition: CrackFrontDefinition.C:1675
CrackFrontDefinition
Works on top of NodalNormalsPreprocessor.
Definition: CrackFrontDefinition.h:36
JIntegral
This postprocessor computes the J-Integral.
Definition: JIntegral.h:28
JIntegral::_q_curr_elem
std::vector< Real > _q_curr_elem
Definition: JIntegral.h:53
JIntegral::_q_function_type
MooseEnum _q_function_type
Definition: JIntegral.h:52
JIntegral::JIntegral
JIntegral(const InputParameters &parameters)
Definition: JIntegral.C:51
CrackFrontDefinition::DomainIntegralTopologicalQFunction
Real DomainIntegralTopologicalQFunction(unsigned int crack_front_point_index, unsigned int ring_index, const Node *const current_node) const
Definition: CrackFrontDefinition.C:1729
JIntegral.h
JIntegral::_Eshelby_tensor
const MaterialProperty< RankTwoTensor > & _Eshelby_tensor
Definition: JIntegral.h:44
defineLegacyParams
defineLegacyParams(JIntegral)
JIntegral::_J_thermal_term_vec
const MaterialProperty< RealVectorValue > * _J_thermal_term_vec
Definition: JIntegral.h:45
validParams
InputParameters validParams()
CrackFrontDefinition::getCrackDirection
const RealVectorValue & getCrackDirection(const unsigned int point_index) const
Definition: CrackFrontDefinition.C:1090
JIntegral::getValue
virtual Real getValue()
Definition: JIntegral.C:176
CrackFrontDefinition::treatAs2D
bool treatAs2D() const
Definition: CrackFrontDefinition.h:59
JIntegral::initialSetup
virtual void initialSetup()
Definition: JIntegral.C:74
JIntegral::computeIntegral
virtual Real computeIntegral()
Definition: JIntegral.C:137
JIntegral::_youngs_modulus
Real _youngs_modulus
Definition: JIntegral.h:49
JIntegral::_dphi_curr_elem
const std::vector< std::vector< RealGradient > > * _dphi_curr_elem
Definition: JIntegral.h:55
JIntegral::_ring_index
unsigned int _ring_index
Definition: JIntegral.h:50
RankTwoTensorTempl< Real >
CrackFrontDefinition::getCrackFrontBackwardSegmentLength
Real getCrackFrontBackwardSegmentLength(const unsigned int point_index) const
Definition: CrackFrontDefinition.C:1084
JIntegral::computeQpIntegral
virtual Real computeQpIntegral()
Definition: JIntegral.C:83
JIntegral::validParams
static InputParameters validParams()
Definition: JIntegral.C:22
JIntegral::_has_symmetry_plane
bool _has_symmetry_plane
Definition: JIntegral.h:47
CrackFrontDefinition::getCrackFrontForwardSegmentLength
Real getCrackFrontForwardSegmentLength(const unsigned int point_index) const
Definition: CrackFrontDefinition.C:1078
JIntegral::_phi_curr_elem
const std::vector< std::vector< Real > > * _phi_curr_elem
Definition: JIntegral.h:54
JIntegral::_convert_J_to_K
bool _convert_J_to_K
Definition: JIntegral.h:46
registerMooseObject
registerMooseObject("TensorMechanicsApp", JIntegral)