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 : #include "ACSwitching.h" 11 : 12 : registerMooseObject("PhaseFieldApp", ACSwitching); 13 : registerMooseObject("PhaseFieldApp", ADACSwitching); 14 : 15 : template <bool is_ad> 16 : InputParameters 17 492 : ACSwitchingTempl<is_ad>::validParams() 18 : { 19 492 : InputParameters params = ACSwitchingBase<is_ad>::validParams(); 20 492 : params.addClassDescription( 21 : "Kernel for Allen-Cahn equation that adds derivatives of switching functions and energies"); 22 984 : params.addRequiredParam<std::vector<MaterialPropertyName>>( 23 : "Fj_names", "List of free energies for each phase. Place in same order as hj_names!"); 24 984 : params.addRequiredParam<std::vector<MaterialPropertyName>>( 25 : "hj_names", "Switching Function Materials that provide h. Place in same order as Fj_names!"); 26 492 : return params; 27 0 : } 28 : 29 : template <bool is_ad> 30 264 : ACSwitchingTempl<is_ad>::ACSwitchingTempl(const InputParameters & parameters) 31 : : ACSwitchingBase<is_ad>(parameters), 32 264 : _etai_name(_var.name()), 33 792 : _Fj_names(this->template getParam<std::vector<MaterialPropertyName>>("Fj_names")), 34 264 : _num_j(_Fj_names.size()), 35 264 : _prop_Fj(_num_j), 36 528 : _hj_names(this->template getParam<std::vector<MaterialPropertyName>>("hj_names")), 37 528 : _prop_dhjdetai(_num_j) 38 : { 39 : // check passed in parameter vectors 40 264 : if (_num_j != _hj_names.size()) 41 0 : this->paramError("hj_names", "Need to pass in as many hj_names as Fj_names"); 42 : 43 : // reserve space and set phase material properties 44 855 : for (unsigned int n = 0; n < _num_j; ++n) 45 : { 46 : // get phase free energy 47 591 : _prop_Fj[n] = &this->template getGenericMaterialProperty<Real, is_ad>(_Fj_names[n]); 48 : 49 : // get first derivative of the switching functions 50 591 : _prop_dhjdetai[n] = 51 1182 : &this->template getMaterialPropertyDerivative<Real, is_ad>(_hj_names[n], _etai_name); 52 : } 53 264 : } 54 : 55 178 : ACSwitching::ACSwitching(const InputParameters & parameters) 56 : : ACSwitchingTempl<false>(parameters), 57 356 : _prop_dFjdarg(_num_j), 58 178 : _prop_d2hjdetai2(_num_j), 59 356 : _prop_d2hjdetaidarg(_num_j) 60 : { 61 : // reserve space and set phase material properties 62 576 : for (unsigned int n = 0; n < _num_j; ++n) 63 : { 64 : // get derivatives of the phase free energy and the switching functions 65 398 : _prop_dFjdarg[n].resize(_n_args); 66 398 : _prop_d2hjdetai2[n] = 67 796 : &getMaterialPropertyDerivative<Real>(_hj_names[n], _etai_name, _etai_name); 68 398 : _prop_d2hjdetaidarg[n].resize(_n_args); 69 : 70 1608 : for (unsigned int i = 0; i < _n_args; ++i) 71 : { 72 : // Get derivatives of all Fj wrt all coupled variables 73 1210 : _prop_dFjdarg[n][i] = &getMaterialPropertyDerivative<Real>(_Fj_names[n], i); 74 : 75 : // Get second derivatives of all hj wrt eta_i and all coupled variables 76 1210 : _prop_d2hjdetaidarg[n][i] = &getMaterialPropertyDerivative<Real>(_hj_names[n], _etai_name, i); 77 : } 78 : } 79 178 : } 80 : 81 : template <bool is_ad> 82 : void 83 201 : ACSwitchingTempl<is_ad>::initialSetup() 84 : { 85 201 : ACSwitchingBase<is_ad>::initialSetup(); 86 603 : for (unsigned int n = 0; n < _num_j; ++n) 87 1206 : this->template validateNonlinearCoupling<GenericReal<is_ad>>(_hj_names[n]); 88 201 : } 89 : 90 : void 91 136 : ACSwitching::initialSetup() 92 : { 93 136 : ACSwitchingTempl<false>::initialSetup(); 94 408 : for (unsigned int n = 0; n < _num_j; ++n) 95 816 : validateNonlinearCoupling<Real>(_Fj_names[n]); 96 136 : } 97 : 98 : Real 99 150039848 : ACSwitching::computeDFDOP(PFFunctionType type) 100 : { 101 : Real sum = 0.0; 102 : 103 150039848 : switch (type) 104 : { 105 : case Residual: 106 418971192 : for (unsigned int n = 0; n < _num_j; ++n) 107 279314128 : sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp]; 108 : 109 : return sum; 110 : 111 : case Jacobian: 112 31148352 : for (unsigned int n = 0; n < _num_j; ++n) 113 20765568 : sum += (*_prop_d2hjdetai2[n])[_qp] * (*_prop_Fj[n])[_qp]; 114 : 115 10382784 : return _phi[_j][_qp] * sum; 116 : } 117 : 118 0 : mooseError("Invalid type passed in to ACSwitching::computeDFDOP"); 119 : } 120 : 121 : ADReal 122 34928820 : ADACSwitching::computeDFDOP() 123 : { 124 34928820 : ADReal sum = 0.0; 125 104786460 : for (unsigned int n = 0; n < _num_j; ++n) 126 139715280 : sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp]; 127 34928820 : return sum; 128 : } 129 : 130 : Real 131 113063808 : ACSwitching::computeQpOffDiagJacobian(unsigned int jvar) 132 : { 133 : // get the coupled variable jvar is referring to 134 : const unsigned int cvar = mapJvarToCvar(jvar); 135 : 136 : // first get dependence of mobility _L on other variables using parent class 137 : // member function 138 113063808 : Real res = ACBulk<Real>::computeQpOffDiagJacobian(jvar); 139 : 140 : // Then add dependence of ACSwitching on other variables 141 : Real sum = 0.0; 142 339191424 : for (unsigned int n = 0; n < _num_j; ++n) 143 226127616 : sum += (*_prop_d2hjdetaidarg[n][cvar])[_qp] * (*_prop_Fj[n])[_qp] + 144 226127616 : (*_prop_dhjdetai[n])[_qp] * (*_prop_dFjdarg[n][cvar])[_qp]; 145 : 146 113063808 : res += _L[_qp] * sum * _phi[_j][_qp] * _test[_i][_qp]; 147 : 148 113063808 : return res; 149 : } 150 : 151 : template class ACSwitchingTempl<false>; 152 : template class ACSwitchingTempl<true>;