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 : #pragma once 11 : 12 : #include "MatDiffusionBase.h" 13 : #include "RankThreeTensor.h" 14 : 15 : template <typename T> 16 : struct GradientType; 17 : 18 : template <> 19 : struct GradientType<Real> 20 : { 21 : typedef RealVectorValue type; 22 : }; 23 : 24 : /** 25 : * In the long term the GradientType struct can be eliminated by using the specialization of 26 : * libmesh::TensorTools::IncrementRank for RankTwoTensor, this will require changing the derived 27 : * class MatAnisoDiffusion and several other classes from RealTensorValue to RankTwoTensor 28 : */ 29 : template <> 30 : struct GradientType<RealTensorValue> 31 : { 32 : typedef RankThreeTensor type; 33 : }; 34 : 35 : template <typename T> 36 : class PolycrystalMatDiffusionBase : public MatDiffusionBase<T> 37 : { 38 : public: 39 : static InputParameters validParams(); 40 : 41 : PolycrystalMatDiffusionBase(const InputParameters & parameters); 42 : 43 : protected: 44 : virtual Real computeQpOffDiagJacobian(unsigned int jvar) override; 45 : /// Number of grain order parameters for cases where there is dependence on grain OP gradients 46 : const unsigned int _op_num; 47 : 48 : /// diffusion coefficient derivatives w.r.t. variables that have explicit dependence on gradients 49 : const MaterialProperty<typename GradientType<T>::type> & _dDdgradc; 50 : std::vector<const MaterialProperty<typename GradientType<T>::type> *> _dDdgradeta; 51 : 52 : /// For solid-pore systems, mame of the order parameter identifies the solid-pore surface 53 : unsigned int _surface_op_var; 54 : 55 : /// Variable to allow user to control whether grain OP gradient contributions are added to Jacobian 56 : const bool _add_grain_op_gradients; 57 : }; 58 : 59 : template <typename T> 60 : InputParameters 61 92 : PolycrystalMatDiffusionBase<T>::validParams() 62 : { 63 92 : InputParameters params = MatDiffusionBase<T>::validParams(); 64 184 : params.addCoupledVar( 65 : "surface_op_var", 66 : "Name of the order parameter for solid-pore surface. For use when diffusivity " 67 : "depends on these OP gradients, leave this parameter un-set otherwise. "); 68 184 : params.addCoupledVarWithAutoBuild( 69 : "grain_op_vars", "var_name_base", "op_num", "Array of grain order parameter variables"); 70 184 : params.addParam<bool>( 71 : "add_grain_op_gradients", 72 184 : true, 73 : "Whether grain order parameter gradient contributions are added to Jacobian."); 74 92 : return params; 75 0 : } 76 : 77 : template <typename T> 78 48 : PolycrystalMatDiffusionBase<T>::PolycrystalMatDiffusionBase(const InputParameters & parameters) 79 : : MatDiffusionBase<T>(parameters), 80 48 : _op_num(this->coupledComponents("grain_op_vars")), 81 192 : _dDdgradc(this->template getMaterialPropertyDerivative<typename GradientType<T>::type>( 82 96 : this->isParamValid("D_name") ? "D_name" : "diffusivity", "gradc")), 83 48 : _dDdgradeta(_op_num), 84 84 : _surface_op_var(this->isCoupled("surface_op_var") ? this->coupled("surface_op_var") 85 : : libMesh::invalid_uint), 86 144 : _add_grain_op_gradients(this->template getParam<bool>("add_grain_op_gradients")) 87 : { 88 48 : if (_add_grain_op_gradients) 89 48 : for (unsigned int j = 0; j < _op_num; ++j) 90 0 : _dDdgradeta[j] = 91 0 : &this->template getMaterialPropertyDerivative<typename GradientType<T>::type>( 92 0 : this->isParamValid("D_name") ? "D_name" : "diffusivity", 93 : ("gradgr" + Moose::stringify(j))); 94 48 : } 95 : 96 : template <typename T> 97 : Real 98 51158656 : PolycrystalMatDiffusionBase<T>::computeQpOffDiagJacobian(unsigned int jvar) 99 : { 100 51158656 : Real sum = MatDiffusionBase<T>::computeQpOffDiagJacobian(jvar); 101 51158656 : if (jvar == _surface_op_var) 102 13009664 : sum += _dDdgradc[this->_qp] * this->_grad_phi[this->_j][this->_qp] * this->_grad_v[this->_qp] * 103 13009664 : this->_grad_test[this->_i][this->_qp]; 104 : 105 51158656 : if (_add_grain_op_gradients) 106 : { 107 51158656 : for (unsigned int k = 0; k < _op_num; ++k) 108 0 : if (jvar == this->coupled("grain_op_vars", k)) 109 0 : sum += (*_dDdgradeta[k])[this->_qp] * this->_grad_phi[this->_j][this->_qp] * 110 0 : this->_grad_v[this->_qp] * this->_grad_test[this->_i][this->_qp]; 111 : } 112 : 113 51158656 : return sum; 114 : }