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 "GeneralizedPlaneStrainUserObject.h" 11 : #include "RankTwoTensor.h" 12 : #include "RankFourTensor.h" 13 : #include "Function.h" 14 : #include "Assembly.h" 15 : #include "UserObjectInterface.h" 16 : 17 : #include "libmesh/quadrature.h" 18 : 19 : registerMooseObject("SolidMechanicsApp", GeneralizedPlaneStrainUserObject); 20 : 21 : InputParameters 22 388 : GeneralizedPlaneStrainUserObject::validParams() 23 : { 24 388 : InputParameters params = ElementUserObject::validParams(); 25 388 : params.addClassDescription( 26 : "Generalized plane strain UserObject to provide residual and diagonal Jacobian entries."); 27 776 : params.addParam<UserObjectName>("subblock_index_provider", 28 : "SubblockIndexProvider user object name"); 29 776 : params.addParam<FunctionName>("out_of_plane_pressure_function", 30 : "Function used to prescribe pressure (applied toward the body) in " 31 : "the out-of-plane direction"); 32 776 : params.addDeprecatedParam<FunctionName>( 33 : "out_of_plane_pressure", 34 : "Function used to prescribe pressure (applied toward the body) in the out-of-plane direction " 35 : "(y for 1D Axisymmetric or z for 2D Cartesian problems)", 36 : "This has been replaced by 'out_of_plane_pressure_function'"); 37 776 : params.addParam<MaterialPropertyName>("out_of_plane_pressure_material", 38 : "0", 39 : "Material used to prescribe pressure (applied toward the " 40 : "body) in the out-of-plane direction"); 41 776 : MooseEnum outOfPlaneDirection("x y z", "z"); 42 776 : params.addParam<MooseEnum>( 43 : "out_of_plane_direction", outOfPlaneDirection, "The direction of the out-of-plane strain."); 44 776 : params.addDeprecatedParam<Real>( 45 : "factor", 46 : "Scale factor applied to prescribed out-of-plane pressure (both material and function)", 47 : "This has been replaced by 'pressure_factor'"); 48 776 : params.addParam<Real>( 49 : "pressure_factor", 50 : "Scale factor applied to prescribed out-of-plane pressure (both material and function)"); 51 776 : params.addParam<std::string>("base_name", "Material properties base name"); 52 1552 : params.set<ExecFlagEnum>("execute_on") = {EXEC_LINEAR, EXEC_NONLINEAR}; 53 : 54 388 : return params; 55 776 : } 56 : 57 194 : GeneralizedPlaneStrainUserObject::GeneralizedPlaneStrainUserObject( 58 194 : const InputParameters & parameters) 59 : : ElementUserObject(parameters), 60 194 : _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""), 61 388 : _Jacobian_mult(getMaterialProperty<RankFourTensor>(_base_name + "Jacobian_mult")), 62 388 : _stress(getMaterialProperty<RankTwoTensor>(_base_name + "stress")), 63 194 : _subblock_id_provider(nullptr), 64 194 : _out_of_plane_pressure_function(parameters.isParamSetByUser("out_of_plane_pressure_function") 65 388 : ? &getFunction("out_of_plane_pressure_function") 66 376 : : parameters.isParamSetByUser("out_of_plane_pressure") 67 194 : ? &getFunction("out_of_plane_pressure") 68 : : nullptr), 69 388 : _out_of_plane_pressure_material(getMaterialProperty<Real>("out_of_plane_pressure_material")), 70 388 : _pressure_factor(parameters.isParamSetByUser("pressure_factor") 71 400 : ? getParam<Real>("pressure_factor") 72 376 : : parameters.isParamSetByUser("factor") ? getParam<Real>("factor") 73 194 : : 1.0) 74 : { 75 388 : if (parameters.isParamSetByUser("out_of_plane_pressure_function") && 76 206 : parameters.isParamSetByUser("out_of_plane_pressure")) 77 0 : mooseError("Cannot specify both 'out_of_plane_pressure_function' and 'out_of_plane_pressure'"); 78 206 : if (parameters.isParamSetByUser("pressure_factor") && parameters.isParamSetByUser("factor")) 79 0 : mooseError("Cannot specify both 'pressure_factor' and 'factor'"); 80 194 : } 81 : 82 : void 83 17494 : GeneralizedPlaneStrainUserObject::initialize() 84 : { 85 34988 : if (isParamValid("subblock_index_provider")) 86 0 : _subblock_id_provider = &getUserObject<SubblockIndexProvider>("subblock_index_provider"); 87 17494 : if (_assembly.coordSystem() == Moose::COORD_XYZ) 88 34136 : _scalar_out_of_plane_strain_direction = getParam<MooseEnum>("out_of_plane_direction"); 89 426 : else if (_assembly.coordSystem() == Moose::COORD_RZ) 90 426 : _scalar_out_of_plane_strain_direction = 1; 91 : else 92 0 : mooseError("Unsupported coordinate system for generalized plane strain formulation"); 93 : 94 17494 : unsigned int max_size = _subblock_id_provider ? _subblock_id_provider->getMaxSubblockIndex() : 1; 95 17494 : _residual.assign(max_size, 0.0); 96 17494 : _reference_residual.assign(max_size, 0.0); 97 17494 : _jacobian.assign(max_size, 0.0); 98 17494 : } 99 : 100 : void 101 35624 : GeneralizedPlaneStrainUserObject::execute() 102 : { 103 : const unsigned int subblock_id = 104 35624 : _subblock_id_provider ? _subblock_id_provider->getSubblockIndex(*_current_elem) : 0; 105 : 106 170584 : for (unsigned int _qp = 0; _qp < _qrule->n_points(); _qp++) 107 : { 108 : const Real out_of_plane_pressure = 109 134960 : ((_out_of_plane_pressure_function 110 134960 : ? _out_of_plane_pressure_function->value(_t, _q_point[_qp]) 111 134960 : : 0.0) + 112 134960 : _out_of_plane_pressure_material[_qp]) * 113 134960 : _pressure_factor; 114 : 115 : // residual, integral of stress_zz for COORD_XYZ 116 134960 : _residual[subblock_id] += _JxW[_qp] * _coord[_qp] * 117 134960 : (_stress[_qp](_scalar_out_of_plane_strain_direction, 118 134960 : _scalar_out_of_plane_strain_direction) + 119 : out_of_plane_pressure); 120 : 121 134960 : _reference_residual[subblock_id] += std::abs( 122 134960 : _JxW[_qp] * _coord[_qp] * 123 134960 : _stress[_qp](_scalar_out_of_plane_strain_direction, _scalar_out_of_plane_strain_direction)); 124 : 125 : // diagonal jacobian, integral of C(2, 2, 2, 2) for COORD_XYZ 126 134960 : _jacobian[subblock_id] += _JxW[_qp] * _coord[_qp] * 127 134960 : _Jacobian_mult[_qp](_scalar_out_of_plane_strain_direction, 128 : _scalar_out_of_plane_strain_direction, 129 : _scalar_out_of_plane_strain_direction, 130 : _scalar_out_of_plane_strain_direction); 131 : } 132 35624 : } 133 : 134 : void 135 0 : GeneralizedPlaneStrainUserObject::threadJoin(const UserObject & uo) 136 : { 137 : const auto & gpsuo = static_cast<const GeneralizedPlaneStrainUserObject &>(uo); 138 0 : for (unsigned int i = 0; i < _residual.size(); ++i) 139 : { 140 0 : _residual[i] += gpsuo._residual[i]; 141 0 : _reference_residual[i] += gpsuo._reference_residual[i]; 142 0 : _jacobian[i] += gpsuo._jacobian[i]; 143 : } 144 0 : } 145 : 146 : void 147 17494 : GeneralizedPlaneStrainUserObject::finalize() 148 : { 149 17494 : gatherSum(_residual); 150 17494 : gatherSum(_reference_residual); 151 17494 : gatherSum(_jacobian); 152 17494 : } 153 : 154 : Real 155 10144 : GeneralizedPlaneStrainUserObject::returnResidual(unsigned int scalar_var_id) const 156 : { 157 10144 : if (_residual.size() <= scalar_var_id) 158 0 : mooseError("Index out of bounds!"); 159 : 160 10144 : return _residual[scalar_var_id]; 161 : } 162 : 163 : Real 164 80 : GeneralizedPlaneStrainUserObject::returnReferenceResidual(unsigned int scalar_var_id) const 165 : { 166 : // At startup, the GeneralizedPlaneStrainReferenceResidual class can ask for this value 167 : // before it has been computed. Return 0.0 in this case. The only way size will stay 168 : // zero is if initialize is never called. 169 80 : if (_reference_residual.size() == 0) 170 : return 0.0; 171 : 172 80 : if (_residual.size() <= scalar_var_id) 173 0 : mooseError("Index out of bounds!"); 174 : 175 80 : return _reference_residual[scalar_var_id]; 176 : } 177 : 178 : Real 179 1372 : GeneralizedPlaneStrainUserObject::returnJacobian(unsigned int scalar_var_id) const 180 : { 181 1372 : if (_jacobian.size() <= scalar_var_id) 182 0 : mooseError("Index out of bounds!"); 183 : 184 1372 : return _jacobian[scalar_var_id]; 185 : }