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 "CHBulk.h" 13 : 14 : /** 15 : * CahnHilliardBase implements the residual of the Cahn-Hilliard 16 : * equation in a general way that can be templated to a scalar or 17 : * tensor mobility. 18 : */ 19 : template <typename T> 20 : class CahnHilliardBase : public CHBulk<T> 21 : { 22 : public: 23 : CahnHilliardBase(const InputParameters & parameters); 24 : 25 : static InputParameters validParams(); 26 : virtual void initialSetup(); 27 : 28 : protected: 29 : typedef typename CHBulk<T>::PFFunctionType PFFunctionType; 30 : virtual RealGradient computeGradDFDCons(PFFunctionType type); 31 : virtual Real computeQpOffDiagJacobian(unsigned int jvar); 32 : 33 : // Explicitly declare the use of the following members of the parent class 34 : // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members 35 : using CHBulk<T>::_M; 36 : using CHBulk<T>::_i; 37 : using CHBulk<T>::_j; 38 : using CHBulk<T>::_qp; 39 : using CHBulk<T>::_var; 40 : using CHBulk<T>::_phi; 41 : using CHBulk<T>::_grad_u; 42 : using CHBulk<T>::_grad_phi; 43 : using CHBulk<T>::_grad_test; 44 : using CHBulk<T>::_coupled_moose_vars; 45 : using CHBulk<T>::_subproblem; 46 : using CHBulk<T>::_tid; 47 : 48 : private: 49 : const unsigned int _nvar; 50 : std::vector<const MaterialProperty<Real> *> _second_derivatives; 51 : std::vector<const MaterialProperty<Real> *> _third_derivatives; 52 : std::vector<std::vector<const MaterialProperty<Real> *>> _third_cross_derivatives; 53 : std::vector<const VariableGradient *> _grad_vars; 54 : }; 55 : 56 : template <typename T> 57 : InputParameters 58 260 : CahnHilliardBase<T>::validParams() 59 : { 60 260 : InputParameters params = CHBulk<Real>::validParams(); 61 260 : params.addClassDescription("Cahn-Hilliard Kernel that uses a DerivativeMaterial Free Energy"); 62 520 : params.addRequiredParam<MaterialPropertyName>( 63 : "f_name", "Base name of the free energy function F defined in a DerivativeParsedMaterial"); 64 520 : params.addCoupledVar("displacement_gradients", 65 : "Vector of displacement gradient variables (see " 66 : "Modules/PhaseField/DisplacementGradients " 67 : "action)"); 68 260 : return params; 69 0 : } 70 : 71 : template <typename T> 72 138 : CahnHilliardBase<T>::CahnHilliardBase(const InputParameters & parameters) 73 : : CHBulk<T>(parameters), 74 138 : _nvar(_coupled_moose_vars.size()), 75 138 : _second_derivatives(_nvar + 1), 76 138 : _third_derivatives(_nvar + 1), 77 138 : _third_cross_derivatives(_nvar), 78 276 : _grad_vars(_nvar + 1) 79 : { 80 : // derivatives w.r.t. and gradients of the kernel variable 81 138 : _second_derivatives[0] = 82 276 : &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), _var.name()); 83 138 : _third_derivatives[0] = &this->template getMaterialPropertyDerivative<Real>( 84 138 : "f_name", _var.name(), _var.name(), _var.name()); 85 138 : _grad_vars[0] = &(_grad_u); 86 : 87 : // Iterate over all coupled variables 88 177 : for (unsigned int i = 0; i < _nvar; ++i) 89 : { 90 39 : const VariableName iname = _coupled_moose_vars[i]->name(); 91 39 : if (iname == _var.name()) 92 : { 93 0 : if (this->isCoupled("args")) 94 0 : this->paramError( 95 : "args", "The kernel variable should not be specified in the coupled `args` parameter."); 96 : else 97 0 : this->paramError("coupled_variables", 98 : "The kernel variable should not be specified in the coupled " 99 : "`coupled_variables` parameter."); 100 : } 101 39 : _second_derivatives[i + 1] = 102 78 : &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), iname); 103 39 : _third_derivatives[i + 1] = &this->template getMaterialPropertyDerivative<Real>( 104 39 : "f_name", _var.name(), _var.name(), iname); 105 : 106 39 : _third_cross_derivatives[i].resize(_nvar); 107 132 : for (unsigned int j = 0; j < _nvar; ++j) 108 : { 109 93 : VariableName jname = _coupled_moose_vars[j]->name(); 110 93 : _third_cross_derivatives[i][j] = 111 186 : &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), iname, jname); 112 : } 113 : 114 39 : _grad_vars[i + 1] = &_subproblem.getStandardVariable(_tid, iname).gradSln(); 115 : } 116 138 : } 117 : 118 : template <typename T> 119 : void 120 120 : CahnHilliardBase<T>::initialSetup() 121 : { 122 : /** 123 : * Check if both the non-linear as well as the auxiliary variables variables 124 : * are coupled. Derivatives with respect to both types of variables contribute 125 : * the residual. 126 : */ 127 480 : this->template validateCoupling<Real>("f_name", _var.name()); 128 120 : this->template validateDerivativeMaterialPropertyBase<Real>("f_name"); 129 120 : } 130 : 131 : template <typename T> 132 : RealGradient 133 97486424 : CahnHilliardBase<T>::computeGradDFDCons(PFFunctionType type) 134 : { 135 : RealGradient res = 0.0; 136 : 137 97486424 : switch (type) 138 : { 139 : case CHBulk<T>::Residual: 140 149901264 : for (unsigned int i = 0; i <= _nvar; ++i) 141 87538536 : res += (*_grad_vars[i])[_qp] * (*_second_derivatives[i])[_qp]; 142 : return res; 143 : 144 35123696 : case CHBulk<T>::Jacobian: 145 35123696 : res = _grad_phi[_j][_qp] * (*_second_derivatives[0])[_qp]; 146 72296928 : for (unsigned int i = 0; i <= _nvar; ++i) 147 37173232 : res += _phi[_j][_qp] * (*_grad_vars[i])[_qp] * (*_third_derivatives[i])[_qp]; 148 : return res; 149 : } 150 : 151 0 : mooseError("Internal error"); 152 : } 153 : 154 : template <typename T> 155 : Real 156 22962176 : CahnHilliardBase<T>::computeQpOffDiagJacobian(unsigned int jvar) 157 : { 158 : // get the coupled variable jvar is referring to 159 : const unsigned int cvar = this->mapJvarToCvar(jvar); 160 : 161 22962176 : RealGradient J = _grad_u[_qp] * _phi[_j][_qp] * (*_third_derivatives[cvar + 1])[_qp] + 162 22962176 : _grad_phi[_j][_qp] * (*_second_derivatives[cvar + 1])[_qp]; 163 : 164 45924352 : for (unsigned int i = 0; i < _nvar; ++i) 165 22962176 : J += _phi[_j][_qp] * (*_grad_vars[i + 1])[_qp] * (*_third_cross_derivatives[i][cvar])[_qp]; 166 : 167 22962176 : return CHBulk<T>::computeQpOffDiagJacobian(jvar) + _M[_qp] * _grad_test[_i][_qp] * J; 168 : }