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 28615 : KernelScalarBase::validParams() 22 : { 23 28615 : InputParameters params = Kernel::validParams(); 24 : // This parameter can get renamed in derived class to a more relevant variable name 25 28615 : params.addCoupledVar("scalar_variable", "Primary coupled scalar variable"); 26 28615 : params.addParam<bool>("compute_scalar_residuals", true, "Whether to compute scalar residuals"); 27 85845 : params.addParam<bool>( 28 57230 : "compute_field_residuals", true, "Whether to compute residuals for the field variable."); 29 28615 : return params; 30 0 : } 31 : 32 45 : KernelScalarBase::KernelScalarBase(const InputParameters & parameters) 33 : : Kernel(parameters), 34 45 : _use_scalar(isParamValid("scalar_variable") ? true : false), 35 45 : _compute_scalar_residuals(!_use_scalar ? false : getParam<bool>("compute_scalar_residuals")), 36 45 : _compute_field_residuals(getParam<bool>("compute_field_residuals")), 37 45 : _kappa_var_ptr(_use_scalar ? getScalarVar("scalar_variable", 0) : nullptr), 38 45 : _kappa_var(_use_scalar ? _kappa_var_ptr->number() : 0), 39 45 : _k_order(_use_scalar ? _kappa_var_ptr->order() : 0), 40 90 : _kappa(_use_scalar ? (_is_implicit ? _kappa_var_ptr->sln() : _kappa_var_ptr->slnOld()) : _zero) 41 : { 42 45 : } 43 : 44 : void 45 195 : KernelScalarBase::computeResidual() 46 : { 47 195 : if (_compute_field_residuals) 48 195 : Kernel::computeResidual(); // compute and assemble regular variable contributions 49 : 50 195 : if (_compute_scalar_residuals) 51 131 : computeScalarResidual(); 52 192 : } 53 : 54 : void 55 131 : KernelScalarBase::computeScalarResidual() 56 : { 57 131 : std::vector<Real> scalar_residuals(_k_order); 58 : 59 1283 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 60 : { 61 1155 : initScalarQpResidual(); 62 2307 : for (_h = 0; _h < _k_order; _h++) 63 1155 : scalar_residuals[_h] += _JxW[_qp] * _coord[_qp] * computeScalarQpResidual(); 64 : } 65 : 66 128 : addResiduals( 67 128 : _assembly, scalar_residuals, _kappa_var_ptr->dofIndices(), _kappa_var_ptr->scalingFactor()); 68 128 : } 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 64 : KernelScalarBase::computeScalarJacobian() 82 : { 83 64 : _local_ke.resize(_k_order, _k_order); 84 : 85 640 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 86 : { 87 576 : initScalarQpJacobian(_kappa_var); 88 1152 : for (_h = 0; _h < _k_order; _h++) 89 1152 : for (_l = 0; _l < _k_order; _l++) 90 576 : _local_ke(_h, _l) += _JxW[_qp] * _coord[_qp] * computeScalarQpJacobian(); 91 : } 92 : 93 256 : addJacobian(_assembly, 94 64 : _local_ke, 95 64 : _kappa_var_ptr->dofIndices(), 96 64 : _kappa_var_ptr->dofIndices(), 97 64 : _kappa_var_ptr->scalingFactor()); 98 64 : } 99 : 100 : void 101 96 : KernelScalarBase::computeOffDiagJacobian(const unsigned int jvar_num) 102 : { 103 96 : if (_use_scalar) 104 : { 105 64 : if (jvar_num == variable().number()) // column for this kernel's variable 106 : { 107 64 : if (_compute_field_residuals) 108 64 : Kernel::computeJacobian(); // d-_var-residual / d-_var 109 64 : if (_compute_scalar_residuals) 110 64 : 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 32 : if (jvar_num == variable().number()) // column for this kernel's variable 126 : { 127 32 : if (_compute_field_residuals) 128 32 : 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 64 : KernelScalarBase::computeScalarOffDiagJacobian(const unsigned int jvar_num) 140 : { 141 64 : const auto & jvar = getVariable(jvar_num); 142 64 : 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 64 : const auto jvar_size = jvar.phiSize(); 148 64 : _local_ke.resize(_k_order, jvar_size); 149 : 150 640 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 151 : { 152 576 : initScalarQpOffDiagJacobian(jvar); 153 1152 : for (_h = 0; _h < _k_order; _h++) 154 5760 : for (_j = 0; _j < jvar_size; _j++) 155 5184 : _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 256 : addJacobian(_assembly, 164 64 : _local_ke, 165 64 : _kappa_var_ptr->dofIndices(), 166 64 : jvar.dofIndices(), 167 64 : _kappa_var_ptr->scalingFactor()); 168 64 : } 169 : 170 : void 171 64 : KernelScalarBase::computeOffDiagJacobianScalarLocal(const unsigned int svar_num) 172 : { 173 : // Get dofs and order of this scalar; at least one will be _kappa_var 174 64 : const auto & svar = _sys.getScalarVariable(_tid, svar_num); 175 64 : const unsigned int s_order = svar.order(); 176 64 : _local_ke.resize(_test.size(), s_order); 177 : 178 640 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 179 : { 180 576 : initScalarQpJacobian(svar_num); 181 5760 : for (_i = 0; _i < _test.size(); _i++) 182 10368 : for (_l = 0; _l < s_order; _l++) 183 5184 : _local_ke(_i, _l) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobianScalar(svar_num); 184 : } 185 : 186 64 : addJacobian(_assembly, _local_ke, _var.dofIndices(), svar.dofIndices(), _var.scalingFactor()); 187 64 : } 188 : 189 : void 190 64 : KernelScalarBase::computeOffDiagJacobianScalar(const unsigned int svar_num) 191 : { 192 64 : precalculateOffDiagJacobianScalar(svar_num); 193 64 : if (_use_scalar) 194 : { 195 64 : if (svar_num == variable().number()) // column for this kernel's variable 196 : // this kernel's variable is not a scalar 197 0 : return; 198 64 : 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 64 : if (_compute_field_residuals) 204 64 : computeOffDiagJacobianScalarLocal(svar_num); // d-_var-residual / d-_kappa 205 64 : if (_compute_scalar_residuals) 206 64 : 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 : }