21 params.addClassDescription(
22 "Class for computing and outputing components and scalar quantities "
23 "of nodal rank two strain and stress tensors for bond-based and ordinary "
24 "state-based peridynamic models");
26 params.addRequiredCoupledVar(
"displacements",
"Nonlinear variable names for the displacements");
27 params.addCoupledVar(
"temperature",
"Nonlinear variable name for the temperature");
28 params.addCoupledVar(
"scalar_out_of_plane_strain",
29 "Scalar variable for strain in the out-of-plane direction");
30 params.addParam<
bool>(
"plane_stress",
false,
"Plane stress problem or not");
31 params.addParam<Real>(
"youngs_modulus", 0.0,
"Material constant: Young's modulus");
32 params.addParam<Real>(
"poissons_ratio", 0.0,
"Material constant: Poisson's ratio");
33 params.addParam<Real>(
34 "thermal_expansion_coeff", 0.0,
"Value of material thermal expansion coefficient");
35 params.addParam<Real>(
"stress_free_temperature", 0.0,
"Stress free temperature");
36 params.addRequiredParam<std::string>(
38 "Parameter to set which rank two tensor: total_strain, mechanical_strain or stress");
39 params.addRequiredParam<std::string>(
"output_type",
"Type of output: component or scalar");
40 params.addParam<MooseEnum>(
42 params.addParam<
unsigned int>(
43 "index_i", 0,
"The index i of ij for the tensor to output (0, 1, 2)");
44 params.addParam<
unsigned int>(
45 "index_j", 0,
"The index j of ij for the tensor to output (0, 1, 2)");
46 params.addParam<Point>(
"point1",
48 "Start point for axis used to calculate some direction dependent material "
49 "tensor scalar quantities");
50 params.addParam<Point>(
"point2",
52 "End point for axis used to calculate some direction dependent material "
53 "tensor scalar quantities");
60 _has_temp(isCoupled(
"temperature")),
61 _temp_var(_has_temp ? getVar(
"temperature", 0) : nullptr),
62 _bond_status_var(&_subproblem.getStandardVariable(_tid,
"bond_status")),
63 _scalar_out_of_plane_strain_coupled(isCoupledScalar(
"scalar_out_of_plane_strain")),
64 _scalar_out_of_plane_strain(_scalar_out_of_plane_strain_coupled
65 ? coupledScalarValue(
"scalar_out_of_plane_strain")
67 _plane_stress(getParam<bool>(
"plane_stress")),
68 _youngs_modulus(getParam<Real>(
"youngs_modulus")),
69 _poissons_ratio(getParam<Real>(
"poissons_ratio")),
70 _alpha(getParam<Real>(
"thermal_expansion_coeff")),
71 _temp_ref(getParam<Real>(
"stress_free_temperature")),
72 _rank_two_tensor(getParam<std::string>(
"rank_two_tensor")),
73 _output_type(getParam<std::string>(
"output_type")),
74 _scalar_type(getParam<MooseEnum>(
"scalar_type")),
75 _i(getParam<unsigned int>(
"index_i")),
76 _j(getParam<unsigned int>(
"index_j")),
77 _point1(parameters.get<Point>(
"point1")),
78 _point2(parameters.get<Point>(
"point2"))
81 mooseError(
"NodalRankTwoPD operates on nodal variable!");
83 if (coupledComponents(
"displacements") !=
_dim)
84 mooseError(
"Number of displacements should be the same as problem dimension!");
85 for (
unsigned int i = 0; i < coupledComponents(
"displacements"); ++i)
86 _disp_var.push_back(getVar(
"displacements", i));
89 !isParamValid(
"poissons_ratio"))
90 mooseError(
"Both Young's modulus and Poisson's ratio must be provided for stress calculation");
92 std::vector<Real> iso_const(2);
98 _Cijkl.fillFromInputVector(iso_const, RankFourTensor::symmetric_isotropic);
100 if (
_has_temp && !isParamValid(
"thermal_expansion_coeff"))
101 mooseError(
"thermal_expansion_coeff is required when temperature is coupled");
103 if (
_output_type ==
"component" && !(isParamValid(
"index_i") || isParamValid(
"index_j")))
104 mooseError(
"The output_type is 'component', but no 'index_i' and 'index_j' are provided!");
106 if (
_output_type ==
"scalar" && !isParamValid(
"scalar_type"))
107 mooseError(
"The output_type is 'scalar', but no 'scalar_type' is provided!");
115 Point p = Point(0, 0, 0);
123 mooseError(
"NodalRankTwoPD Error: Pass valid rank two tensor: total_strain, "
124 "mechanical_strain or stress");
131 mooseError(
"NodalRankTwoPD Error: Pass valid output type - component or scalar");
140 std::vector<dof_id_type> bonds =
_pdmesh.
getBonds(_current_node->id());
144 RankTwoTensor shape, dgrad, delta(RankTwoTensor::initIdentity);
148 shape(2, 2) = dgrad(2, 2) = 1.0;
152 current_vector = 0.0;
154 for (
unsigned int j = 0; j < neighbors.size(); ++j)
156 Node * node_j =
_pdmesh.nodePtr(neighbors[j]);
158 for (
unsigned int k = 0; k <
_dim; ++k)
160 origin_vector(k) = (*node_j)(k) - (*
_pdmesh.nodePtr(_current_node->id()))(k);
161 current_vector(k) = origin_vector(k) +
_disp_var[k]->getNodalValue(*node_j) -
162 _disp_var[k]->getNodalValue(*_current_node);
164 Real origin_length = origin_vector.norm();
166 for (
unsigned int k = 0; k <
_dim; ++k)
167 for (
unsigned int l = 0; l <
_dim; ++l)
170 vol_j * horizon / origin_length * origin_vector(k) * origin_vector(l) * bond_status_ij;
172 vol_j * horizon / origin_length * current_vector(k) * origin_vector(l) * bond_status_ij;
177 dgrad *= shape.inverse();
180 RankTwoTensor total_strain = 0.5 * (dgrad.transpose() * dgrad - delta);
193 -(
_Cijkl(2, 2, 0, 0) * mstrain00 +
_Cijkl(2, 2, 1, 1) * mstrain11) /
_Cijkl(2, 2, 2, 2);
199 -(
_Cijkl(2, 2, 0, 0) * total_strain(0, 0) +
_Cijkl(2, 2, 1, 1) * total_strain(1, 1)) /
216 RankTwoTensor mechanical_strain = total_strain - thermal_strain;
218 return mechanical_strain;