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 "ComputeInterfaceStress.h" 11 : #include "RankTwoTensor.h" 12 : 13 : registerMooseObject("SolidMechanicsApp", ComputeInterfaceStress); 14 : 15 : InputParameters 16 48 : ComputeInterfaceStress::validParams() 17 : { 18 48 : InputParameters params = Material::validParams(); 19 48 : params.addClassDescription( 20 : "Stress in the plane of an interface defined by the gradient of an order parameter"); 21 96 : params.addCoupledVar("v", 22 : "Order parameters that define the interface. The interface is the region " 23 : "where the gradient of this order parameter is non-zero."); 24 96 : params.addRequiredParam<std::vector<Real>>("stress", 25 : "Interfacial planar stress magnitude (one " 26 : "value to apply to all order parameters or one value " 27 : "per order parameter listed in 'v')"); 28 96 : params.addRangeCheckedParam<std::vector<Real>>( 29 : "op_range", 30 : {1.0}, 31 : "op_range > 0.0", 32 : "Range over which order parameters change across an " 33 : "interface. By default order parameters are assumed to " 34 : "vary from 0 to 1"); 35 96 : params.addParam<MaterialPropertyName>("planar_stress_name", 36 : "extra_stress", 37 : "Material property name for the interfacial planar stress"); 38 48 : return params; 39 0 : } 40 : 41 36 : ComputeInterfaceStress::ComputeInterfaceStress(const InputParameters & parameters) 42 : : Material(parameters), 43 36 : _nvar(coupledComponents("v")), 44 36 : _grad_v(_nvar), 45 72 : _op_range(getParam<std::vector<Real>>("op_range")), 46 72 : _stress(getParam<std::vector<Real>>("stress")), 47 36 : _planar_stress( 48 144 : declareProperty<RankTwoTensor>(getParam<MaterialPropertyName>("planar_stress_name"))) 49 : { 50 36 : if (_stress.size() == 1) 51 18 : _stress.assign(_nvar, _stress[0]); 52 36 : if (_stress.size() != _nvar) 53 0 : paramError("stress", "Supply either one single stress or one per order parameter"); 54 : 55 36 : if (_op_range.size() == 1) 56 : _op_range.assign(_nvar, _op_range[0]); 57 36 : if (_op_range.size() != _nvar) 58 0 : paramError("op_range", "Supply either one single op_range or one per order parameter"); 59 : 60 90 : for (MooseIndex(_grad_v) i = 0; i < _nvar; ++i) 61 : { 62 54 : _grad_v[i] = &coupledGradient("v", i); 63 54 : _stress[i] /= _op_range[i]; 64 : } 65 36 : } 66 : 67 : void 68 16000 : ComputeInterfaceStress::computeQpProperties() 69 : { 70 16000 : auto & S = _planar_stress[_qp]; 71 : S.zero(); 72 : 73 : // loop over interface variables 74 40000 : for (MooseIndex(_grad_v) i = 0; i < _nvar; ++i) 75 : { 76 : // compute norm square of the order parameter gradient 77 24000 : const Real grad_norm_sq = (*_grad_v[i])[_qp].norm_sq(); 78 : 79 : // gradient square is zero -> no interface -> no interfacial stress contribution 80 24000 : if (grad_norm_sq < libMesh::TOLERANCE) 81 6720 : continue; 82 : 83 : const Real nx = (*_grad_v[i])[_qp](0); 84 : const Real ny = (*_grad_v[i])[_qp](1); 85 : const Real nz = (*_grad_v[i])[_qp](2); 86 17280 : const Real s = _stress[i] / std::sqrt(grad_norm_sq); 87 : 88 17280 : S(0, 0) += (ny * ny + nz * nz) * s; 89 17280 : S(0, 1) += -nx * ny * s; 90 17280 : S(1, 1) += (nx * nx + nz * nz) * s; 91 17280 : S(0, 2) += -nx * nz * s; 92 17280 : S(1, 2) += -ny * nz * s; 93 17280 : S(2, 2) += (nx * nx + ny * ny) * s; 94 : } 95 : 96 : // fill in symmetrically 97 16000 : S(1, 0) = S(0, 1); 98 16000 : S(2, 0) = S(0, 2); 99 16000 : S(2, 1) = S(1, 2); 100 16000 : }