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 "VectorTransientAbsorbingBC.h" 11 : #include "ElectromagneticConstants.h" 12 : #include "ElectromagneticEnums.h" 13 : #include "Function.h" 14 : #include <complex> 15 : 16 : registerMooseObject("ElectromagneticsApp", VectorTransientAbsorbingBC); 17 : 18 : InputParameters 19 82 : VectorTransientAbsorbingBC::validParams() 20 : { 21 82 : InputParameters params = VectorIntegratedBC::validParams(); 22 82 : params.addClassDescription( 23 : "First order transient absorbing boundary condition for vector variables."); 24 164 : params.addParam<FunctionName>("admittance", 25 164 : 1 / (EM::mu_0 * EM::c), 26 : "Intrinsic admittance of the infinite medium (default is " 27 : "$\\sqrt{\\frac{\\epsilon_0}{\\mu_0}} = \\frac{1}{\\mu_0 c}$, or " 28 : "the admittance of free space)."); 29 164 : MooseEnum component("real imaginary"); 30 164 : params.addParam<MooseEnum>( 31 : "component", component, "Variable field component (real or imaginary)."); 32 164 : params.addRequiredCoupledVar("coupled_field", "Coupled field variable."); 33 82 : return params; 34 82 : } 35 : 36 44 : VectorTransientAbsorbingBC::VectorTransientAbsorbingBC(const InputParameters & parameters) 37 : : VectorIntegratedBC(parameters), 38 : 39 44 : _admittance(getFunction("admittance")), 40 : 41 88 : _component(getParam<MooseEnum>("component")), 42 : 43 44 : _coupled_val(coupledVectorValue("coupled_field")), 44 44 : _coupled_var_num(coupled("coupled_field")), 45 : 46 44 : _u_dot(dot()), 47 44 : _coupled_dot(coupledVectorDot("coupled_field")), 48 44 : _du_dot_du(dotDu()), 49 88 : _coupled_dot_du(coupledVectorDotDu("coupled_field")) 50 : { 51 44 : } 52 : 53 : Real 54 50232 : VectorTransientAbsorbingBC::computeQpResidual() 55 : { 56 : // Initialize field_dot components 57 50232 : std::complex<double> field_dot_0(0, 0); 58 50232 : std::complex<double> field_dot_1(0, 0); 59 50232 : std::complex<double> field_dot_2(0, 0); 60 : 61 : // Create E_dot for residual based on component parameter 62 50232 : if (_component == EM::REAL) 63 : { 64 25116 : field_dot_0.real(_u_dot[_qp](0)); 65 25116 : field_dot_0.imag(_coupled_dot[_qp](0)); 66 : 67 25116 : field_dot_1.real(_u_dot[_qp](1)); 68 25116 : field_dot_1.imag(_coupled_dot[_qp](1)); 69 : 70 25116 : field_dot_2.real(_u_dot[_qp](2)); 71 25116 : field_dot_2.imag(_coupled_dot[_qp](2)); 72 : } 73 : else 74 : { 75 25116 : field_dot_0.real(_coupled_dot[_qp](0)); 76 25116 : field_dot_0.imag(_u_dot[_qp](0)); 77 : 78 25116 : field_dot_1.real(_coupled_dot[_qp](1)); 79 25116 : field_dot_1.imag(_u_dot[_qp](1)); 80 : 81 25116 : field_dot_2.real(_coupled_dot[_qp](2)); 82 25116 : field_dot_2.imag(_u_dot[_qp](2)); 83 : } 84 : VectorValue<std::complex<double>> field_dot(field_dot_0, field_dot_1, field_dot_2); 85 : 86 : // Calculate solution field contribution to BC residual 87 50232 : std::complex<double> p_dot_test = EM::mu_0 * _admittance.value(_t, _q_point[_qp]) * 88 50232 : _test[_i][_qp].cross(_normals[_qp]) * 89 50232 : _normals[_qp].cross(field_dot); 90 : 91 : std::complex<double> res = -p_dot_test; 92 : 93 50232 : if (_component == EM::REAL) 94 25116 : return res.real(); 95 : else 96 25116 : return res.imag(); 97 : } 98 : 99 : Real 100 75348 : VectorTransientAbsorbingBC::computeQpJacobian() 101 : { 102 : RealVectorValue prefix = 103 75348 : EM::mu_0 * _admittance.value(_t, _q_point[_qp]) * _test[_i][_qp].cross(_normals[_qp]); 104 : 105 75348 : return prefix * _normals[_qp].cross(_du_dot_du[_qp] * _phi[_j][_qp]); 106 : } 107 : 108 : Real 109 75348 : VectorTransientAbsorbingBC::computeQpOffDiagJacobian(unsigned int jvar) 110 : { 111 75348 : if (jvar == _coupled_var_num) 112 : { 113 : RealVectorValue prefix = 114 75348 : EM::mu_0 * _admittance.value(_t, _q_point[_qp]) * _test[_i][_qp].cross(_normals[_qp]); 115 : 116 75348 : return prefix * _normals[_qp].cross(_coupled_dot_du[_qp] * _phi[_j][_qp]); 117 : } 118 : else 119 : return 0.0; 120 : }