Line data Source code
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 "HillConstants.h"
11 :
12 : registerMooseObject("SolidMechanicsApp", HillConstants);
13 : registerMooseObject("SolidMechanicsApp", ADHillConstants);
14 :
15 : template <bool is_ad>
16 : InputParameters
17 504 : HillConstantsTempl<is_ad>::validParams()
18 : {
19 504 : InputParameters params = Material::validParams();
20 504 : params.addClassDescription("Build and rotate the Hill Tensor. It can be used with other Hill "
21 : "plasticity and creep materials.");
22 1008 : params.addParam<std::string>("base_name",
23 : "Optional parameter that allows the user to define "
24 : "multiple mechanics material systems on the same "
25 : "block, i.e. for multiple phases");
26 1008 : params.addRequiredRangeCheckedParam<std::vector<Real>>("hill_constants",
27 : "hill_constants_size = 6",
28 : "Hill material constants in order: F, "
29 : "G, H, L, M, N");
30 1008 : params.addParam<RealVectorValue>(
31 : "rotation_angles",
32 : "Provide the rotation angles for the transformation matrix. "
33 : "This should be a vector that provides "
34 : "the rotation angles about z-, x-, and z-axis, respectively in degrees.");
35 1008 : params.addParam<std::vector<FunctionName>>(
36 : "function_names",
37 : {},
38 : "A set of functions that describe the evolution of anisotropy with temperature");
39 1008 : params.addParam<bool>(
40 : "use_large_rotation",
41 1008 : true,
42 : "Whether to rotate the Hill tensor (anisotropic parameters) to account for large kinematic "
43 : "rotations. It's recommended to set it to true if large displacements are to be expected.");
44 1008 : params.addParam<bool>("use_automatic_differentiation",
45 1008 : false,
46 : "Whether thermal contact depends on automatic differentiation materials.");
47 1008 : params.addCoupledVar("temperature", "Coupled temperature");
48 504 : return params;
49 0 : }
50 :
51 : template <bool is_ad>
52 378 : HillConstantsTempl<is_ad>::HillConstantsTempl(const InputParameters & parameters)
53 : : Material(parameters),
54 510 : _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
55 756 : _use_large_rotation(getParam<bool>("use_large_rotation")),
56 756 : _rotation_total_hill(_use_large_rotation ? &declareGenericProperty<RankTwoTensor, is_ad>(
57 378 : _base_name + "rotation_total_hill")
58 : : nullptr),
59 756 : _rotation_total_hill_old(_use_large_rotation
60 756 : ? &this->template getMaterialPropertyOldByName<RankTwoTensor>(
61 378 : _base_name + "rotation_total_hill")
62 : : nullptr),
63 378 : _rotation_increment(_use_large_rotation ? &getGenericMaterialProperty<RankTwoTensor, is_ad>(
64 : "rotation_increment")
65 : : nullptr),
66 756 : _hill_constants_input(getParam<std::vector<Real>>("hill_constants")),
67 378 : _hill_tensor(6, 6),
68 378 : _hill_constant_material(declareProperty<std::vector<Real>>(_base_name + "hill_constants")),
69 756 : _hill_tensor_material(_use_large_rotation
70 378 : ? &declareProperty<DenseMatrix<Real>>(_base_name + "hill_tensor")
71 : : nullptr),
72 1134 : _zxz_angles(isParamValid("rotation_angles") ? getParam<RealVectorValue>("rotation_angles")
73 : : RealVectorValue(0.0, 0.0, 0.0)),
74 378 : _transformation_tensor(6, 6),
75 756 : _has_temp(isParamValid("temperature")),
76 378 : _temperature(_has_temp ? coupledValue("temperature") : _zero),
77 1134 : _function_names(getParam<std::vector<FunctionName>>("function_names")),
78 378 : _num_functions(_function_names.size()),
79 378 : _functions(_num_functions),
80 756 : _rigid_body_rotation_tensor(_zxz_angles)
81 : {
82 : // Transform to radians, used throughout the class.
83 1512 : for (unsigned i = 0; i < 3; i++)
84 1134 : _zxz_angles(i) *= libMesh::pi / 180.0;
85 :
86 378 : if (_has_temp && _num_functions != 6)
87 0 : paramError("function_names",
88 : "Six functions need to be provided to determine the evolution of Hill's "
89 : "coefficients F, G, H, L, M, and N, when temperature dependency is selected.");
90 :
91 378 : for (unsigned int i = 0; i < _num_functions; i++)
92 : {
93 0 : _functions[i] = &getFunctionByName(_function_names[i]);
94 0 : if (_functions[i] == nullptr)
95 0 : paramError("function_names", "Function names provided cannot retrieve a function.");
96 : }
97 :
98 378 : if (!_has_temp && !_use_large_rotation)
99 0 : rotateHillConstants(_hill_constants_input);
100 378 : }
101 :
102 : template <bool is_ad>
103 : void
104 32160 : HillConstantsTempl<is_ad>::initQpStatefulProperties()
105 : {
106 32160 : if (_use_large_rotation)
107 : {
108 32160 : RankTwoTensor identity_rotation(RankTwoTensor::initIdentity);
109 32160 : (*_rotation_total_hill)[_qp] = identity_rotation;
110 : }
111 32160 : }
112 :
113 : template <bool is_ad>
114 : void
115 20986000 : HillConstantsTempl<is_ad>::computeQpProperties()
116 : {
117 : // Account for finite strain rotation influence on anisotropic coefficients
118 20986000 : if (_use_large_rotation)
119 : {
120 20986000 : (*_rotation_total_hill)[_qp] = (*_rotation_increment)[_qp] * (*_rotation_total_hill_old)[_qp];
121 :
122 : // Make sure to provide the original coefficients to the orientation transformation
123 20986000 : _hill_constant_material[_qp].resize(6);
124 20986000 : _hill_constant_material[_qp] = _hill_constants_input;
125 : }
126 :
127 : // Account for temperature dependency
128 20986000 : if (_has_temp)
129 : {
130 0 : _hill_constant_material[_qp].resize(6);
131 :
132 0 : for (unsigned int i = 0; i < 6; i++)
133 0 : _hill_constant_material[_qp][i] = _functions[i]->value(_temperature[_qp]);
134 : }
135 :
136 : // We need to update the coefficients whether we use temperature dependency or large rotation
137 : // kinematics (or both)
138 20986000 : if (_has_temp || _use_large_rotation)
139 20986000 : rotateHillConstants(_hill_constant_material[_qp]);
140 :
141 : // Update material coefficients whether or not they are temperature-dependent
142 20986000 : if (_use_large_rotation)
143 20986000 : (*_hill_tensor_material)[_qp] = _hill_tensor;
144 :
145 : // To be used only for simple cases (axis-aligned, small deformation)
146 20986000 : if (!_use_large_rotation)
147 : {
148 0 : _hill_constant_material[_qp].resize(6);
149 0 : _hill_constant_material[_qp][0] = -_hill_tensor(1, 2); // F
150 0 : _hill_constant_material[_qp][1] = -_hill_tensor(0, 2); // G
151 0 : _hill_constant_material[_qp][2] = -_hill_tensor(0, 1); // H
152 0 : _hill_constant_material[_qp][3] = _hill_tensor(4, 4) / 2.0; // L
153 0 : _hill_constant_material[_qp][4] = _hill_tensor(5, 5) / 2.0; // M
154 0 : _hill_constant_material[_qp][5] = _hill_tensor(3, 3) / 2.0; // N
155 : }
156 20986000 : }
157 :
158 : template <bool is_ad>
159 : void
160 20986000 : HillConstantsTempl<is_ad>::rotateHillConstants(const std::vector<Real> & hill_constants_input)
161 : {
162 : // Rotation due to rigid body motion and large deformation
163 20986000 : RankTwoTensor total_rotation_matrix;
164 :
165 20986000 : if (_use_large_rotation)
166 20986000 : total_rotation_matrix =
167 20986000 : MetaPhysicL::raw_value((*_rotation_total_hill)[_qp]) * _rigid_body_rotation_tensor;
168 : else
169 0 : total_rotation_matrix = _rigid_body_rotation_tensor;
170 :
171 : const RankTwoTensor & trm = total_rotation_matrix;
172 :
173 : const Real & F = hill_constants_input[0];
174 : const Real & G = hill_constants_input[1];
175 : const Real & H = hill_constants_input[2];
176 : const Real & L = hill_constants_input[3];
177 : const Real & M = hill_constants_input[4];
178 : const Real & N = hill_constants_input[5];
179 :
180 20986000 : _hill_tensor.zero();
181 :
182 20986000 : _hill_tensor(0, 0) = G + H;
183 20986000 : _hill_tensor(1, 1) = F + H;
184 20986000 : _hill_tensor(2, 2) = F + G;
185 20986000 : _hill_tensor(0, 1) = _hill_tensor(1, 0) = -H;
186 20986000 : _hill_tensor(0, 2) = _hill_tensor(2, 0) = -G;
187 20986000 : _hill_tensor(1, 2) = _hill_tensor(2, 1) = -F;
188 :
189 20986000 : _hill_tensor(3, 3) = 2.0 * N;
190 20986000 : _hill_tensor(4, 4) = 2.0 * L;
191 20986000 : _hill_tensor(5, 5) = 2.0 * M;
192 :
193 : // Transformed the Hill tensor given the total rotation matrix
194 : // MEHRABADI, MORTEZA M.; COWIN, STEPHEN C. (1990). EIGENTENSORS OF LINEAR ANISOTROPIC ELASTIC
195 : // MATERIALS. The Quarterly Journal of Mechanics and Applied Mathematics, 43(1), 15-41.
196 : // doi:10.1093/qjmam/43.1.15
197 20986000 : DenseMatrix<Real> transformation_matrix_n(6, 6);
198 : const static std::array<std::size_t, 3> a = {{1, 0, 0}};
199 : const static std::array<std::size_t, 3> b = {{2, 2, 1}};
200 83944000 : for (std::size_t i = 0; i < 3; ++i)
201 251832000 : for (std::size_t j = 0; j < 3; ++j)
202 : {
203 188874000 : transformation_matrix_n(i, j) = trm(i, j) * trm(i, j);
204 188874000 : transformation_matrix_n(i + 3, j) = 2.0 * trm((i + 1) % 3, j) * trm((i + 2) % 3, j);
205 188874000 : transformation_matrix_n(j, i + 3) = trm(j, (i + 1) % 3) * trm(j, (i + 2) % 3);
206 188874000 : transformation_matrix_n(i + 3, j + 3) =
207 188874000 : trm(a[i], a[j]) * trm(b[i], b[j]) + trm(a[i], b[j]) * trm(b[i], a[j]);
208 : }
209 :
210 20986000 : _hill_tensor.left_multiply(transformation_matrix_n);
211 20986000 : _hill_tensor.right_multiply_transpose(transformation_matrix_n);
212 20986000 : }
213 :
214 : template class HillConstantsTempl<false>;
215 : template class HillConstantsTempl<true>;
|