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 "Kernel.h" 13 : #include "JvarMapInterface.h" 14 : #include "DerivativeMaterialInterface.h" 15 : #include "RankThreeTensor.h" 16 : 17 : template <typename T> 18 : struct GradientType; 19 : 20 : template <> 21 : struct GradientType<Real> 22 : { 23 : typedef RealVectorValue type; 24 : }; 25 : 26 : /** 27 : * In the long term the GradientType struct can be eliminated by using the specialization of 28 : * libmesh::TensorTools::IncrementRank for RankTwoTensor, this will require changing the derived 29 : * class MatAnisoDiffusion and several other classes from RealTensorValue to RankTwoTensor 30 : */ 31 : template <> 32 : struct GradientType<RealTensorValue> 33 : { 34 : typedef RankThreeTensor type; 35 : }; 36 : 37 : /** 38 : * This class template implements a diffusion kernel with a mobility that can vary 39 : * spatially and can depend on variables in the simulation. Two classes are derived from 40 : * this template, MatDiffusion for isotropic diffusion and MatAnisoDiffusion for 41 : * anisotropic diffusion. 42 : * 43 : * \tparam T Type of the diffusion coefficient parameter. This can be Real for 44 : * isotropic diffusion or RealTensorValue for the general anisotropic case. 45 : */ 46 : template <typename T> 47 : class MatDiffusionBase : public DerivativeMaterialInterface<JvarMapKernelInterface<Kernel>> 48 : { 49 : public: 50 : static InputParameters validParams(); 51 : 52 : MatDiffusionBase(const InputParameters & parameters); 53 : 54 : virtual void initialSetup() override; 55 : 56 : protected: 57 : virtual Real computeQpResidual() override; 58 : virtual Real computeQpJacobian() override; 59 : virtual Real computeQpOffDiagJacobian(unsigned int jvar) override; 60 : virtual Real computeQpCJacobian(); 61 : 62 : /// diffusion coefficient 63 : const MaterialProperty<T> & _D; 64 : 65 : /// diffusion coefficient derivative w.r.t. the kernel variable 66 : const MaterialProperty<T> & _dDdc; 67 : 68 : /// diffusion coefficient derivatives w.r.t. coupled variables 69 : std::vector<const MaterialProperty<T> *> _dDdarg; 70 : 71 : /// diffusion coefficient derivatives w.r.t. variables that have explicit dependence on gradients 72 : const MaterialProperty<typename GradientType<T>::type> & _dDdgradc; 73 : 74 : /// is the kernel used in a coupled form? 75 : const bool _is_coupled; 76 : 77 : /// int label for the Concentration 78 : unsigned int _v_var; 79 : 80 : /// Gradient of the concentration 81 : const VariableGradient & _grad_v; 82 : 83 : /// For solid-pore systems, mame of the order parameter identifies the solid-pore surface 84 : unsigned int _surface_op_var; 85 : }; 86 : 87 : template <typename T> 88 : InputParameters 89 16689 : MatDiffusionBase<T>::validParams() 90 : { 91 16689 : InputParameters params = Kernel::validParams(); 92 16689 : params.addDeprecatedParam<MaterialPropertyName>( 93 : "D_name", 94 : "The name of the diffusivity", 95 : "This parameter has been renamed to 'diffusivity', which is more mnemonic and more conducive " 96 : "to passing a number literal"); 97 16689 : params.addParam<MaterialPropertyName>( 98 : "diffusivity", "D", "The diffusivity value or material property"); 99 16689 : params.addCoupledVar("args", 100 : "Optional vector of arguments for the diffusivity. If provided and " 101 : "diffusivity is a derivative parsed material, Jacobian contributions from " 102 : "the diffusivity will be automatically computed"); 103 16689 : params.addCoupledVar("conc", "Deprecated! Use 'v' instead"); 104 16689 : params.addCoupledVar("v", 105 : "Coupled concentration variable for kernel to operate on; if this " 106 : "is not specified, the kernel's nonlinear variable will be used as " 107 : "usual"); 108 16689 : params.addCoupledVar( 109 : "surface_op_var", 110 : "Name of the order parameter for solid-pore surface. For use when diffusivity " 111 : "depends on these OP gradients, leave this parameter un-set otherwise. "); 112 16689 : return params; 113 0 : } 114 : 115 : template <typename T> 116 1261 : MatDiffusionBase<T>::MatDiffusionBase(const InputParameters & parameters) 117 : : DerivativeMaterialInterface<JvarMapKernelInterface<Kernel>>(parameters), 118 2522 : _D(isParamValid("D_name") ? getMaterialProperty<T>("D_name") 119 1261 : : getMaterialProperty<T>("diffusivity")), 120 2522 : _dDdc(getMaterialPropertyDerivative<T>(isParamValid("D_name") ? "D_name" : "diffusivity", 121 1261 : _var.name())), 122 1261 : _dDdarg(_coupled_moose_vars.size()), 123 3783 : _dDdgradc(getMaterialPropertyDerivative<typename GradientType<T>::type>( 124 2522 : isParamValid("D_name") ? "D_name" : "diffusivity", "gradc")), 125 1261 : _is_coupled(isCoupled("v")), 126 1261 : _v_var(_is_coupled ? coupled("v") : (isCoupled("conc") ? coupled("conc") : _var.number())), 127 3783 : _grad_v(_is_coupled ? coupledGradient("v") 128 2522 : : (isCoupled("conc") ? coupledGradient("conc") : _grad_u)), 129 2522 : _surface_op_var(isCoupled("surface_op_var") ? coupled("surface_op_var") : libMesh::invalid_uint) 130 : { 131 : // deprecated variable parameter conc 132 1261 : if (isCoupled("conc")) 133 0 : mooseDeprecated("In '", name(), "' the parameter 'conc' is deprecated, please use 'v' instead"); 134 : 135 : // fetch derivatives 136 1378 : for (unsigned int i = 0; i < _dDdarg.size(); ++i) 137 351 : _dDdarg[i] = &getMaterialPropertyDerivative<T>( 138 234 : isParamValid("D_name") ? "D_name" : "diffusivity", _coupled_moose_vars[i]->name()); 139 1261 : } 140 : 141 : template <typename T> 142 : void 143 1261 : MatDiffusionBase<T>::initialSetup() 144 : { 145 1261 : validateNonlinearCoupling<Real>(parameters().isParamSetByUser("D_name") ? "D_name" 146 : : "diffusivity"); 147 1261 : } 148 : 149 : template <typename T> 150 : Real 151 35671843 : MatDiffusionBase<T>::computeQpResidual() 152 : { 153 35671843 : return _D[_qp] * _grad_v[_qp] * _grad_test[_i][_qp]; 154 : } 155 : 156 : template <typename T> 157 : Real 158 23976087 : MatDiffusionBase<T>::computeQpJacobian() 159 : { 160 23976087 : Real sum = _phi[_j][_qp] * _dDdc[_qp] * _grad_v[_qp] * _grad_test[_i][_qp]; 161 23976087 : if (!_is_coupled) 162 23976087 : sum += computeQpCJacobian(); 163 : 164 23976087 : return sum; 165 : } 166 : 167 : template <typename T> 168 : Real 169 0 : MatDiffusionBase<T>::computeQpOffDiagJacobian(unsigned int jvar) 170 : { 171 : // get the coupled variable jvar is referring to 172 0 : const unsigned int cvar = mapJvarToCvar(jvar); 173 : 174 0 : Real sum = (*_dDdarg[cvar])[_qp] * _phi[_j][_qp] * _grad_v[_qp] * _grad_test[_i][_qp]; 175 0 : if (jvar == _surface_op_var) 176 0 : sum += _dDdgradc[_qp] * _grad_phi[_j][_qp] * _grad_v[_qp] * _grad_test[_i][_qp]; 177 : 178 0 : if (_v_var == jvar) 179 0 : sum += computeQpCJacobian(); 180 : 181 0 : return sum; 182 : } 183 : 184 : template <typename T> 185 : Real 186 23976087 : MatDiffusionBase<T>::computeQpCJacobian() 187 : { 188 23976087 : return _D[_qp] * _grad_phi[_j][_qp] * _grad_test[_i][_qp]; 189 : }