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 "KernelScalarBase.h" 11 : 12 : #include "Assembly.h" 13 : #include "SubProblem.h" 14 : #include "SystemBase.h" 15 : #include "MooseVariableFE.h" 16 : #include "MooseVariableScalar.h" 17 : 18 : #include "libmesh/quadrature.h" 19 : 20 : InputParameters 21 28621 : KernelScalarBase::validParams() 22 : { 23 28621 : InputParameters params = Kernel::validParams(); 24 : // This parameter can get renamed in derived class to a more relevant variable name 25 28621 : params.addCoupledVar("scalar_variable", "Primary coupled scalar variable"); 26 28621 : params.addParam<bool>("compute_scalar_residuals", true, "Whether to compute scalar residuals"); 27 85863 : params.addParam<bool>( 28 57242 : "compute_field_residuals", true, "Whether to compute residuals for the field variable."); 29 28621 : return params; 30 0 : } 31 : 32 48 : KernelScalarBase::KernelScalarBase(const InputParameters & parameters) 33 : : Kernel(parameters), 34 48 : _use_scalar(isParamValid("scalar_variable") ? true : false), 35 48 : _compute_scalar_residuals(!_use_scalar ? false : getParam<bool>("compute_scalar_residuals")), 36 48 : _compute_field_residuals(getParam<bool>("compute_field_residuals")), 37 48 : _kappa_var_ptr(_use_scalar ? getScalarVar("scalar_variable", 0) : nullptr), 38 48 : _kappa_var(_use_scalar ? _kappa_var_ptr->number() : 0), 39 48 : _k_order(_use_scalar ? _kappa_var_ptr->order() : 0), 40 96 : _kappa(_use_scalar ? (_is_implicit ? _kappa_var_ptr->sln() : _kappa_var_ptr->slnOld()) : _zero) 41 : { 42 48 : } 43 : 44 : void 45 219 : KernelScalarBase::computeResidual() 46 : { 47 219 : if (_compute_field_residuals) 48 219 : Kernel::computeResidual(); // compute and assemble regular variable contributions 49 : 50 219 : if (_compute_scalar_residuals) 51 147 : computeScalarResidual(); 52 216 : } 53 : 54 : void 55 147 : KernelScalarBase::computeScalarResidual() 56 : { 57 147 : std::vector<Real> scalar_residuals(_k_order); 58 : 59 1443 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 60 : { 61 1299 : initScalarQpResidual(); 62 2595 : for (_h = 0; _h < _k_order; _h++) 63 1299 : scalar_residuals[_h] += _JxW[_qp] * _coord[_qp] * computeScalarQpResidual(); 64 : } 65 : 66 144 : addResiduals( 67 144 : _assembly, scalar_residuals, _kappa_var_ptr->dofIndices(), _kappa_var_ptr->scalingFactor()); 68 144 : } 69 : 70 : void 71 0 : KernelScalarBase::computeJacobian() 72 : { 73 0 : if (_compute_field_residuals) 74 0 : Kernel::computeJacobian(); 75 : 76 0 : if (_compute_scalar_residuals) 77 0 : computeScalarJacobian(); 78 0 : } 79 : 80 : void 81 72 : KernelScalarBase::computeScalarJacobian() 82 : { 83 72 : _local_ke.resize(_k_order, _k_order); 84 : 85 720 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 86 : { 87 648 : initScalarQpJacobian(_kappa_var); 88 1296 : for (_h = 0; _h < _k_order; _h++) 89 1296 : for (_l = 0; _l < _k_order; _l++) 90 648 : _local_ke(_h, _l) += _JxW[_qp] * _coord[_qp] * computeScalarQpJacobian(); 91 : } 92 : 93 288 : addJacobian(_assembly, 94 72 : _local_ke, 95 72 : _kappa_var_ptr->dofIndices(), 96 72 : _kappa_var_ptr->dofIndices(), 97 72 : _kappa_var_ptr->scalingFactor()); 98 72 : } 99 : 100 : void 101 108 : KernelScalarBase::computeOffDiagJacobian(const unsigned int jvar_num) 102 : { 103 108 : if (_use_scalar) 104 : { 105 72 : if (jvar_num == variable().number()) // column for this kernel's variable 106 : { 107 72 : if (_compute_field_residuals) 108 72 : Kernel::computeJacobian(); // d-_var-residual / d-_var 109 72 : if (_compute_scalar_residuals) 110 72 : computeScalarOffDiagJacobian(jvar_num); // d-_kappa-residual / d-_var 111 : } 112 0 : else if (jvar_num == _kappa_var) // column for this kernel's scalar variable 113 : // handle these in computeOffDiagJacobianScalar 114 0 : return; 115 : else // some other column for regular variable 116 : { 117 0 : if (_compute_field_residuals) 118 0 : Kernel::computeOffDiagJacobian(jvar_num); // d-_var-residual / d-jvar 119 0 : if (_compute_scalar_residuals) 120 0 : computeScalarOffDiagJacobian(jvar_num); // d-_kappa-residual / d-jvar 121 : } 122 : } 123 : else 124 : { 125 36 : if (jvar_num == variable().number()) // column for this kernel's variable 126 : { 127 36 : if (_compute_field_residuals) 128 36 : Kernel::computeJacobian(); // d-_var-residual / d-_var 129 : } 130 : else // some other column for regular variable 131 : { 132 0 : if (_compute_field_residuals) 133 0 : Kernel::computeOffDiagJacobian(jvar_num); // d-_var-residual / d-jvar 134 : } 135 : } 136 : } 137 : 138 : void 139 72 : KernelScalarBase::computeScalarOffDiagJacobian(const unsigned int jvar_num) 140 : { 141 72 : const auto & jvar = getVariable(jvar_num); 142 72 : if (jvar.fieldType() == Moose::VarFieldType::VAR_FIELD_STANDARD) 143 : { 144 : // Get dofs and order of this variable; at least one will be _var 145 : // const auto & jv0 = static_cast<const MooseVariable &>(jvar); 146 : // const auto & loc_phi = jv0.phi(); 147 72 : const auto jvar_size = jvar.phiSize(); 148 72 : _local_ke.resize(_k_order, jvar_size); 149 : 150 720 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 151 : { 152 648 : initScalarQpOffDiagJacobian(jvar); 153 1296 : for (_h = 0; _h < _k_order; _h++) 154 6480 : for (_j = 0; _j < jvar_size; _j++) 155 5832 : _local_ke(_h, _j) += _JxW[_qp] * _coord[_qp] * computeScalarQpOffDiagJacobian(jvar_num); 156 : } 157 : } 158 0 : else if (jvar.fieldType() == Moose::VarFieldType::VAR_FIELD_ARRAY) 159 0 : mooseError("Array variable cannot be coupled into Kernel Scalar currently"); 160 : else 161 0 : mooseError("Vector variable cannot be coupled into Kernel Scalar currently"); 162 : 163 288 : addJacobian(_assembly, 164 72 : _local_ke, 165 72 : _kappa_var_ptr->dofIndices(), 166 72 : jvar.dofIndices(), 167 72 : _kappa_var_ptr->scalingFactor()); 168 72 : } 169 : 170 : void 171 72 : KernelScalarBase::computeOffDiagJacobianScalarLocal(const unsigned int svar_num) 172 : { 173 : // Get dofs and order of this scalar; at least one will be _kappa_var 174 72 : const auto & svar = _sys.getScalarVariable(_tid, svar_num); 175 72 : const unsigned int s_order = svar.order(); 176 72 : _local_ke.resize(_test.size(), s_order); 177 : 178 720 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 179 : { 180 648 : initScalarQpJacobian(svar_num); 181 6480 : for (_i = 0; _i < _test.size(); _i++) 182 11664 : for (_l = 0; _l < s_order; _l++) 183 5832 : _local_ke(_i, _l) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobianScalar(svar_num); 184 : } 185 : 186 72 : addJacobian(_assembly, _local_ke, _var.dofIndices(), svar.dofIndices(), _var.scalingFactor()); 187 72 : } 188 : 189 : void 190 72 : KernelScalarBase::computeOffDiagJacobianScalar(const unsigned int svar_num) 191 : { 192 72 : precalculateOffDiagJacobianScalar(svar_num); 193 72 : if (_use_scalar) 194 : { 195 72 : if (svar_num == variable().number()) // column for this kernel's variable 196 : // this kernel's variable is not a scalar 197 0 : return; 198 72 : else if (svar_num == _kappa_var) // column for this kernel's scalar variable 199 : { 200 : // Perform assembly using method in Kernel; works for simple cases but not general 201 : // Kernel::computeOffDiagJacobianScalar(svar_num); // d-_var-residual / d-_kappa 202 : // Perform assembly using local_ke like d-_kappa_var-residual / d-_var 203 72 : if (_compute_field_residuals) 204 72 : computeOffDiagJacobianScalarLocal(svar_num); // d-_var-residual / d-_kappa 205 72 : if (_compute_scalar_residuals) 206 72 : computeScalarJacobian(); // d-_kappa-residual / d-_kappa 207 : } 208 : else // some other column for scalar variable 209 : { 210 : // Perform assembly using method in Kernel; works for simple cases but not general 211 : // Kernel::computeOffDiagJacobianScalar(svar_num); // d-_var-residual / d-jvar 212 : // Perform assembly using local_ke like d-_kappa_var-residual / d-_var 213 0 : if (_compute_field_residuals) 214 0 : computeOffDiagJacobianScalarLocal(svar_num); // d-_var-residual / d-svar 215 0 : if (_compute_scalar_residuals) 216 0 : computeScalarOffDiagJacobianScalar(svar_num); // d-_kappa-residual / d-svar 217 : } 218 : } 219 0 : else if (_compute_field_residuals) 220 0 : Kernel::computeOffDiagJacobianScalar(svar_num); // d-_var-residual / d-svar 221 : } 222 : 223 : void 224 0 : KernelScalarBase::computeScalarOffDiagJacobianScalar(const unsigned int svar_num) 225 : { 226 : // Get dofs and order of this scalar; at least one will be _kappa_var 227 0 : const auto & svar = _sys.getScalarVariable(_tid, svar_num); 228 0 : const unsigned int s_order = svar.order(); 229 0 : _local_ke.resize(_k_order, s_order); 230 : 231 0 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 232 : { 233 0 : initScalarQpJacobian(svar_num); 234 0 : for (_h = 0; _h < _k_order; _h++) 235 0 : for (_l = 0; _l < s_order; _l++) 236 0 : _local_ke(_h, _l) += 237 0 : _JxW[_qp] * _coord[_qp] * computeScalarQpOffDiagJacobianScalar(svar_num); 238 : } 239 : 240 0 : addJacobian(_assembly, 241 0 : _local_ke, 242 0 : _kappa_var_ptr->dofIndices(), 243 0 : svar.dofIndices(), 244 0 : _kappa_var_ptr->scalingFactor()); 245 0 : }