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 "Material.h" 14 : #include "JvarMapInterface.h" 15 : #include "DerivativeKernelInterface.h" 16 : 17 : /** 18 : * This is the Cahn-Hilliard equation base class that implements the interfacial or gradient energy 19 : * term of the equation. 20 : * See M.R. Tonks et al. / Computational Materials Science 51 (2012) 20-29 for more information. 21 : */ 22 : template <typename T> 23 : class CHInterfaceBase : public DerivativeMaterialInterface<JvarMapKernelInterface<Kernel>> 24 : { 25 : public: 26 : CHInterfaceBase(const InputParameters & parameters); 27 : 28 : static InputParameters validParams(); 29 : 30 : protected: 31 : virtual Real computeQpResidual(); 32 : virtual Real computeQpJacobian(); 33 : virtual Real computeQpOffDiagJacobian(unsigned int jvar); 34 : 35 : const MaterialProperty<Real> & _kappa; 36 : 37 : ///@{ 38 : /// Mobility material property value and concentration derivatives 39 : const MaterialProperty<T> & _M; 40 : const MaterialProperty<T> & _dMdc; 41 : const MaterialProperty<T> & _d2Mdc2; 42 : ///@} 43 : 44 : ///@{ 45 : /// Variables for second order derivatives 46 : const VariableSecond & _second_u; 47 : const VariableTestSecond & _second_test; 48 : const VariablePhiSecond & _second_phi; 49 : ///@} 50 : 51 : ///Number of variables 52 : unsigned int _nvar; 53 : 54 : ///@{ 55 : /// Mobility derivatives w.r.t. its dependent variables 56 : std::vector<const MaterialProperty<T> *> _dMdarg; 57 : std::vector<const MaterialProperty<T> *> _d2Mdcdarg; 58 : std::vector<std::vector<const MaterialProperty<T> *>> _d2Mdargdarg; 59 : ///@} 60 : 61 : /// Coupled variables used in mobility 62 : std::vector<const VariableGradient *> _coupled_grad_vars; 63 : }; 64 : 65 : template <typename T> 66 222 : CHInterfaceBase<T>::CHInterfaceBase(const InputParameters & parameters) 67 : : DerivativeMaterialInterface<JvarMapKernelInterface<Kernel>>(parameters), 68 222 : _kappa(getMaterialProperty<Real>("kappa_name")), 69 444 : _M(getMaterialProperty<T>("mob_name")), 70 222 : _dMdc(getMaterialPropertyDerivative<T>("mob_name", _var.name())), 71 222 : _d2Mdc2(getMaterialPropertyDerivative<T>("mob_name", _var.name(), _var.name())), 72 222 : _second_u(second()), 73 222 : _second_test(secondTest()), 74 222 : _second_phi(secondPhi()), 75 222 : _nvar(_coupled_moose_vars.size()), 76 222 : _dMdarg(_nvar), 77 222 : _d2Mdcdarg(_nvar), 78 222 : _d2Mdargdarg(_nvar), 79 444 : _coupled_grad_vars(_nvar) 80 : { 81 : // Iterate over all coupled variables 82 234 : for (unsigned int i = 0; i < _nvar; ++i) 83 : { 84 : // Set material property values 85 12 : _dMdarg[i] = &getMaterialPropertyDerivative<T>("mob_name", _coupled_moose_vars[i]->name()); 86 12 : _d2Mdcdarg[i] = 87 24 : &getMaterialPropertyDerivative<T>("mob_name", _var.name(), _coupled_moose_vars[i]->name()); 88 12 : _d2Mdargdarg[i].resize(_nvar); 89 24 : for (unsigned int j = 0; j < _nvar; ++j) 90 12 : _d2Mdargdarg[i][j] = &getMaterialPropertyDerivative<T>( 91 12 : "mob_name", _coupled_moose_vars[i]->name(), _coupled_moose_vars[j]->name()); 92 : 93 : // Set coupled variable gradients 94 12 : _coupled_grad_vars[i] = &coupledGradient("coupled_variables", i); 95 : } 96 222 : } 97 : 98 : template <typename T> 99 : InputParameters 100 420 : CHInterfaceBase<T>::validParams() 101 : { 102 420 : InputParameters params = Kernel::validParams(); 103 420 : params.addClassDescription("Gradient energy Cahn-Hilliard base Kernel"); 104 840 : params.addRequiredParam<MaterialPropertyName>("kappa_name", "The kappa used with the kernel"); 105 840 : params.addRequiredParam<MaterialPropertyName>("mob_name", "The mobility used with the kernel"); 106 840 : params.addCoupledVar("coupled_variables", "Vector of variable arguments of the mobility"); 107 420 : return params; 108 0 : } 109 : 110 : template <typename T> 111 : Real 112 102485152 : CHInterfaceBase<T>::computeQpResidual() 113 : { 114 102485152 : RealGradient grad_M = _dMdc[_qp] * _grad_u[_qp]; 115 105110688 : for (unsigned int i = 0; i < _nvar; ++i) 116 2625536 : grad_M += (*_dMdarg[i])[_qp] * (*_coupled_grad_vars[i])[_qp]; 117 : 118 102485152 : return _kappa[_qp] * _second_u[_qp].tr() * 119 102485152 : ((_M[_qp] * _second_test[_i][_qp]).tr() + grad_M * _grad_test[_i][_qp]); 120 : } 121 : 122 : template <typename T> 123 : Real 124 1233086400 : CHInterfaceBase<T>::computeQpJacobian() 125 : { 126 : // Set the gradient and gradient derivative values 127 1233086400 : RealGradient grad_M = _dMdc[_qp] * _grad_u[_qp]; 128 : 129 : RealGradient dgrad_Mdc = 130 1233086400 : _d2Mdc2[_qp] * _phi[_j][_qp] * _grad_u[_qp] + _dMdc[_qp] * _grad_phi[_j][_qp]; 131 : 132 1265878976 : for (unsigned int i = 0; i < _nvar; ++i) 133 : { 134 32792576 : grad_M += (*_dMdarg[i])[_qp] * (*_coupled_grad_vars[i])[_qp]; 135 32792576 : dgrad_Mdc += (*_d2Mdcdarg[i])[_qp] * _phi[_j][_qp] * (*_coupled_grad_vars[i])[_qp]; 136 : } 137 : 138 : // Jacobian value using product rule 139 1233086400 : Real value = _kappa[_qp] * _second_phi[_j][_qp].tr() * 140 1233086400 : ((_M[_qp] * _second_test[_i][_qp]).tr() + grad_M * _grad_test[_i][_qp]) + 141 1233086400 : _kappa[_qp] * _second_u[_qp].tr() * 142 1233086400 : ((_dMdc[_qp] * _second_test[_i][_qp]).tr() * _phi[_j][_qp] + 143 : dgrad_Mdc * _grad_test[_i][_qp]); 144 : 145 1233086400 : return value; 146 : } 147 : 148 : template <typename T> 149 : Real 150 22962176 : CHInterfaceBase<T>::computeQpOffDiagJacobian(unsigned int jvar) 151 : { 152 : // get the coupled variable jvar is referring to 153 : const unsigned int cvar = mapJvarToCvar(jvar); 154 : 155 : // Set the gradient derivative 156 22962176 : RealGradient dgrad_Mdarg = (*_d2Mdcdarg[cvar])[_qp] * _phi[_j][_qp] * _grad_u[_qp] + 157 22962176 : (*_dMdarg[cvar])[_qp] * _grad_phi[_j][_qp]; 158 : 159 45924352 : for (unsigned int i = 0; i < _nvar; ++i) 160 22962176 : dgrad_Mdarg += (*_d2Mdargdarg[cvar][i])[_qp] * _phi[_j][_qp] * (*_coupled_grad_vars[cvar])[_qp]; 161 : 162 : // Jacobian value using product rule 163 22962176 : Real value = _kappa[_qp] * _second_u[_qp].tr() * 164 22962176 : (((*_dMdarg[cvar])[_qp] * _second_test[_i][_qp]).tr() * _phi[_j][_qp] + 165 22962176 : dgrad_Mdarg * _grad_test[_i][_qp]); 166 : 167 22962176 : return value; 168 : }