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 38 : VectorTransientAbsorbingBC::validParams() 20 : { 21 38 : InputParameters params = VectorIntegratedBC::validParams(); 22 38 : params.addClassDescription( 23 : "First order transient absorbing boundary condition for vector variables."); 24 76 : params.addParam<FunctionName>("admittance", 25 76 : 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 76 : MooseEnum component("real imaginary"); 30 76 : params.addParam<MooseEnum>( 31 : "component", component, "Variable field component (real or imaginary)."); 32 76 : params.addRequiredCoupledVar("coupled_field", "Coupled field variable."); 33 38 : return params; 34 38 : } 35 : 36 20 : VectorTransientAbsorbingBC::VectorTransientAbsorbingBC(const InputParameters & parameters) 37 : : VectorIntegratedBC(parameters), 38 : 39 20 : _admittance(getFunction("admittance")), 40 : 41 40 : _component(getParam<MooseEnum>("component")), 42 : 43 20 : _coupled_val(coupledVectorValue("coupled_field")), 44 20 : _coupled_var_num(coupled("coupled_field")), 45 : 46 20 : _u_dot(dot()), 47 20 : _coupled_dot(coupledVectorDot("coupled_field")), 48 20 : _du_dot_du(dotDu()), 49 40 : _coupled_dot_du(coupledVectorDotDu("coupled_field")) 50 : { 51 20 : } 52 : 53 : Real 54 33672 : VectorTransientAbsorbingBC::computeQpResidual() 55 : { 56 : // Initialize field_dot components 57 33672 : std::complex<double> field_dot_0(0, 0); 58 33672 : std::complex<double> field_dot_1(0, 0); 59 33672 : std::complex<double> field_dot_2(0, 0); 60 : 61 : // Create E_dot for residual based on component parameter 62 33672 : if (_component == EM::REAL) 63 : { 64 16836 : field_dot_0.real(_u_dot[_qp](0)); 65 16836 : field_dot_0.imag(_coupled_dot[_qp](0)); 66 : 67 16836 : field_dot_1.real(_u_dot[_qp](1)); 68 16836 : field_dot_1.imag(_coupled_dot[_qp](1)); 69 : 70 16836 : field_dot_2.real(_u_dot[_qp](2)); 71 16836 : field_dot_2.imag(_coupled_dot[_qp](2)); 72 : } 73 : else 74 : { 75 16836 : field_dot_0.real(_coupled_dot[_qp](0)); 76 16836 : field_dot_0.imag(_u_dot[_qp](0)); 77 : 78 16836 : field_dot_1.real(_coupled_dot[_qp](1)); 79 16836 : field_dot_1.imag(_u_dot[_qp](1)); 80 : 81 16836 : field_dot_2.real(_coupled_dot[_qp](2)); 82 16836 : 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 33672 : std::complex<double> p_dot_test = EM::mu_0 * _admittance.value(_t, _q_point[_qp]) * 88 33672 : _test[_i][_qp].cross(_normals[_qp]) * 89 33672 : _normals[_qp].cross(field_dot); 90 : 91 : std::complex<double> res = -p_dot_test; 92 : 93 33672 : if (_component == EM::REAL) 94 16836 : return res.real(); 95 : else 96 16836 : return res.imag(); 97 : } 98 : 99 : Real 100 50508 : VectorTransientAbsorbingBC::computeQpJacobian() 101 : { 102 : RealVectorValue prefix = 103 50508 : EM::mu_0 * _admittance.value(_t, _q_point[_qp]) * _test[_i][_qp].cross(_normals[_qp]); 104 : 105 50508 : return prefix * _normals[_qp].cross(_du_dot_du[_qp] * _phi[_j][_qp]); 106 : } 107 : 108 : Real 109 50508 : VectorTransientAbsorbingBC::computeQpOffDiagJacobian(unsigned int jvar) 110 : { 111 50508 : if (jvar == _coupled_var_num) 112 : { 113 : RealVectorValue prefix = 114 50508 : EM::mu_0 * _admittance.value(_t, _q_point[_qp]) * _test[_i][_qp].cross(_normals[_qp]); 115 : 116 50508 : return prefix * _normals[_qp].cross(_coupled_dot_du[_qp] * _phi[_j][_qp]); 117 : } 118 : else 119 : return 0.0; 120 : }