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 "CoupledSwitchingTimeDerivative.h" 11 : 12 : registerMooseObject("PhaseFieldApp", CoupledSwitchingTimeDerivative); 13 : registerMooseObject("PhaseFieldApp", ADCoupledSwitchingTimeDerivative); 14 : 15 : template <bool is_ad> 16 : InputParameters 17 375 : CoupledSwitchingTimeDerivativeTempl<is_ad>::validParams() 18 : { 19 375 : InputParameters params = CoupledSwitchingTimeDerivativeBase<is_ad>::validParams(); 20 375 : params.addClassDescription( 21 : "Coupled time derivative Kernel that multiplies the time derivative by " 22 : "$\\frac{dh_\\alpha}{d\\eta_i} F_\\alpha + \\frac{dh_\\beta}{d\\eta_i} F_\\beta + \\dots$"); 23 750 : params.addRequiredParam<std::vector<MaterialPropertyName>>( 24 : "Fj_names", "List of functions for each phase. Place in same order as hj_names!"); 25 750 : params.addRequiredParam<std::vector<MaterialPropertyName>>( 26 : "hj_names", "Switching Function Materials that provide h. Place in same order as Fj_names!"); 27 750 : params.addCoupledVar("coupled_variables", "Vector of variable arguments of Fj and hj"); 28 375 : return params; 29 0 : } 30 : template <bool is_ad> 31 201 : CoupledSwitchingTimeDerivativeTempl<is_ad>::CoupledSwitchingTimeDerivativeTempl( 32 : const InputParameters & parameters) 33 : : DerivativeMaterialInterface<JvarMapKernelInterface<CoupledSwitchingTimeDerivativeBase<is_ad>>>( 34 : parameters), 35 201 : _v_name(this->coupledName("v", 0)), 36 603 : _Fj_names(this->template getParam<std::vector<MaterialPropertyName>>("Fj_names")), 37 201 : _num_j(_Fj_names.size()), 38 201 : _prop_Fj(_num_j), 39 402 : _hj_names(this->template getParam<std::vector<MaterialPropertyName>>("hj_names")), 40 402 : _prop_dhjdetai(_num_j) 41 : { 42 : // check passed in parameter vectors 43 201 : if (_num_j != _hj_names.size()) 44 0 : this->paramError("hj_names", "Need to pass in as many hj_names as Fj_names"); 45 : 46 : // reserve space and set phase material properties 47 645 : for (unsigned int n = 0; n < _num_j; ++n) 48 : { 49 : // get phase free energy 50 444 : _prop_Fj[n] = &this->template getGenericMaterialProperty<Real, is_ad>(_Fj_names[n]); 51 : 52 : // get switching function derivatives wrt eta_i, the nonlinear variable 53 444 : _prop_dhjdetai[n] = 54 888 : &this->template getMaterialPropertyDerivative<Real, is_ad>(_hj_names[n], _v_name); 55 : } 56 201 : } 57 : 58 141 : CoupledSwitchingTimeDerivative::CoupledSwitchingTimeDerivative(const InputParameters & parameters) 59 : : CoupledSwitchingTimeDerivativeTempl<false>(parameters), 60 282 : _prop_dFjdv(_num_j), 61 141 : _prop_dFjdarg(_num_j), 62 141 : _prop_d2hjdetai2(_num_j), 63 282 : _prop_d2hjdetaidarg(_num_j) 64 : { 65 : // reserve space and set phase material properties 66 444 : for (unsigned int n = 0; n < _num_j; ++n) 67 : { 68 : // get phase free energy and derivatives 69 303 : _prop_dFjdv[n] = &getMaterialPropertyDerivative<Real>(_Fj_names[n], _var.name()); 70 303 : _prop_dFjdarg[n].resize(_n_args); 71 : 72 : // get switching function and derivatives wrt eta_i, the nonlinear variable 73 303 : _prop_d2hjdetai2[n] = &getMaterialPropertyDerivative<Real>(_hj_names[n], _v_name, _v_name); 74 303 : _prop_d2hjdetaidarg[n].resize(_n_args); 75 : 76 1643 : for (unsigned int i = 0; i < _n_args; ++i) 77 : { 78 : // Get derivatives of all Fj wrt all coupled variables 79 1340 : _prop_dFjdarg[n][i] = &getMaterialPropertyDerivative<Real>(_Fj_names[n], i); 80 : 81 : // Get second derivatives of all hj wrt eta_i and all coupled variables 82 1340 : _prop_d2hjdetaidarg[n][i] = &getMaterialPropertyDerivative<Real>(_hj_names[n], _v_name, i); 83 : } 84 : } 85 141 : } 86 : 87 : template <bool is_ad> 88 : void 89 159 : CoupledSwitchingTimeDerivativeTempl<is_ad>::initialSetup() 90 : { 91 477 : for (unsigned int n = 0; n < _num_j; ++n) 92 954 : this->template validateNonlinearCoupling<GenericReal<is_ad>>(_hj_names[n]); 93 159 : } 94 : 95 : void 96 120 : CoupledSwitchingTimeDerivative::initialSetup() 97 : { 98 120 : CoupledSwitchingTimeDerivativeTempl<false>::initialSetup(); 99 360 : for (unsigned int n = 0; n < _num_j; ++n) 100 720 : validateNonlinearCoupling<Real>(_Fj_names[n]); 101 120 : } 102 : 103 : Real 104 6740800 : CoupledSwitchingTimeDerivative::computeQpResidual() 105 : { 106 : Real sum = 0.0; 107 20222400 : for (unsigned int n = 0; n < _num_j; ++n) 108 13481600 : sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp]; 109 : 110 6740800 : return CoupledTimeDerivative::computeQpResidual() * sum; 111 : } 112 : 113 : ADReal 114 436020 : ADCoupledSwitchingTimeDerivative::precomputeQpResidual() 115 : { 116 436020 : ADReal sum = 0.0; 117 1308060 : for (unsigned int n = 0; n < _num_j; ++n) 118 1744080 : sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_Fj[n])[_qp]; 119 : 120 872040 : return _v_dot[_qp] * sum; 121 : } 122 : 123 : Real 124 6145600 : CoupledSwitchingTimeDerivative::computeQpJacobian() 125 : { 126 : Real sum = 0.0; 127 18436800 : for (unsigned int n = 0; n < _num_j; ++n) 128 12291200 : sum += (*_prop_dhjdetai[n])[_qp] * (*_prop_dFjdv[n])[_qp]; 129 : 130 6145600 : return CoupledTimeDerivative::computeQpResidual() * sum * _phi[_j][_qp]; 131 : } 132 : 133 : Real 134 16131200 : CoupledSwitchingTimeDerivative::computeQpOffDiagJacobian(unsigned int jvar) 135 : { 136 : // get the coupled variable jvar is referring to 137 : const unsigned int cvar = mapJvarToCvar(jvar); 138 : 139 16131200 : if (jvar == _v_var) 140 : { 141 : Real sum = 0.0; 142 : 143 17745600 : for (unsigned int n = 0; n < _num_j; ++n) 144 11830400 : sum += 145 11830400 : ((*_prop_d2hjdetai2[n])[_qp] * _v_dot[_qp] + (*_prop_dhjdetai[n])[_qp] * _dv_dot[_qp]) * 146 11830400 : (*_prop_Fj[n])[_qp]; 147 : 148 5915200 : return _phi[_j][_qp] * sum * _test[_i][_qp]; 149 : } 150 : 151 : Real sum = 0.0; 152 30648000 : for (unsigned int n = 0; n < _num_j; ++n) 153 20432000 : sum += (*_prop_d2hjdetaidarg[n][cvar])[_qp] * (*_prop_Fj[n])[_qp] + 154 20432000 : (*_prop_dhjdetai[n])[_qp] * (*_prop_dFjdarg[n][cvar])[_qp]; 155 : 156 10216000 : return CoupledTimeDerivative::computeQpResidual() * sum * _phi[_j][_qp]; 157 : } 158 : 159 : template class CoupledSwitchingTimeDerivativeTempl<false>; 160 : template class CoupledSwitchingTimeDerivativeTempl<true>;