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 0 : this->paramError("coupled_variables", 93 : "The kernel variable should not be specified in the coupled " 94 : "`coupled_variables` parameter."); 95 39 : _second_derivatives[i + 1] = 96 78 : &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), iname); 97 39 : _third_derivatives[i + 1] = &this->template getMaterialPropertyDerivative<Real>( 98 39 : "f_name", _var.name(), _var.name(), iname); 99 : 100 39 : _third_cross_derivatives[i].resize(_nvar); 101 132 : for (unsigned int j = 0; j < _nvar; ++j) 102 : { 103 93 : VariableName jname = _coupled_moose_vars[j]->name(); 104 93 : _third_cross_derivatives[i][j] = 105 186 : &this->template getMaterialPropertyDerivative<Real>("f_name", _var.name(), iname, jname); 106 : } 107 : 108 39 : _grad_vars[i + 1] = &_subproblem.getStandardVariable(_tid, iname).gradSln(); 109 : } 110 138 : } 111 : 112 : template <typename T> 113 : void 114 120 : CahnHilliardBase<T>::initialSetup() 115 : { 116 : /** 117 : * Check if both the non-linear as well as the auxiliary variables variables 118 : * are coupled. Derivatives with respect to both types of variables contribute 119 : * the residual. 120 : */ 121 480 : this->template validateCoupling<Real>("f_name", _var.name()); 122 120 : this->template validateDerivativeMaterialPropertyBase<Real>("f_name"); 123 120 : } 124 : 125 : template <typename T> 126 : RealGradient 127 97488104 : CahnHilliardBase<T>::computeGradDFDCons(PFFunctionType type) 128 : { 129 : RealGradient res = 0.0; 130 : 131 97488104 : switch (type) 132 : { 133 : case CHBulk<T>::Residual: 134 149903664 : for (unsigned int i = 0; i <= _nvar; ++i) 135 87539736 : res += (*_grad_vars[i])[_qp] * (*_second_derivatives[i])[_qp]; 136 : return res; 137 : 138 35124176 : case CHBulk<T>::Jacobian: 139 35124176 : res = _grad_phi[_j][_qp] * (*_second_derivatives[0])[_qp]; 140 72297888 : for (unsigned int i = 0; i <= _nvar; ++i) 141 37173712 : res += _phi[_j][_qp] * (*_grad_vars[i])[_qp] * (*_third_derivatives[i])[_qp]; 142 : return res; 143 : } 144 : 145 0 : mooseError("Internal error"); 146 : } 147 : 148 : template <typename T> 149 : Real 150 22962176 : CahnHilliardBase<T>::computeQpOffDiagJacobian(unsigned int jvar) 151 : { 152 : // get the coupled variable jvar is referring to 153 : const unsigned int cvar = this->mapJvarToCvar(jvar); 154 : 155 22962176 : RealGradient J = _grad_u[_qp] * _phi[_j][_qp] * (*_third_derivatives[cvar + 1])[_qp] + 156 22962176 : _grad_phi[_j][_qp] * (*_second_derivatives[cvar + 1])[_qp]; 157 : 158 45924352 : for (unsigned int i = 0; i < _nvar; ++i) 159 22962176 : J += _phi[_j][_qp] * (*_grad_vars[i + 1])[_qp] * (*_third_cross_derivatives[i][cvar])[_qp]; 160 : 161 22962176 : return CHBulk<T>::computeQpOffDiagJacobian(jvar) + _M[_qp] * _grad_test[_i][_qp] * J; 162 : }