https://mooseframework.inl.gov
Loading...
Searching...
No Matches
VectorEMRobinBC.C
Go to the documentation of this file.
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 "VectorEMRobinBC.h"
13#include "Function.h"
14#include <complex>
15
16registerMooseObject("ElectromagneticsApp", VectorEMRobinBC);
17
20{
22 params.addClassDescription("First order Robin-style Absorbing/Port BC for vector variables.");
23 params.addParam<FunctionName>("beta", 1.0, "Scalar wave number.");
24 MooseEnum component("real imaginary");
25 params.addParam<MooseEnum>(
26 "component", component, "Variable field component (real or imaginary).");
27 params.addRequiredCoupledVar("coupled_field", "Coupled field variable.");
28 params.addParam<FunctionName>("real_incoming", 0.0, "Real incoming field vector.");
29 params.addParam<FunctionName>("imag_incoming", 0.0, "Imaginary incoming field vector.");
30 MooseEnum mode("absorbing port", "port");
31 params.addParam<MooseEnum>("mode", mode, "Mode of operation for VectorEMRobinBC.");
32 return params;
33}
34
36 : VectorIntegratedBC(parameters),
37
38 _beta(getFunction("beta")),
39
40 _component(getParam<MooseEnum>("component")),
41
42 _coupled_val(coupledVectorValue("coupled_field")),
43 _coupled_var_num(coupled("coupled_field")),
44
45 _inc_real(getFunction("real_incoming")),
46 _inc_imag(getFunction("imag_incoming")),
47
48 _mode(getParam<MooseEnum>("mode")),
49
50 _real_incoming_was_set(parameters.isParamSetByUser("real_incoming")),
51 _imag_incoming_was_set(parameters.isParamSetByUser("imag_incoming"))
52{
54 {
56 "In ",
57 _name,
58 ", mode was set to Absorbing, while an incoming profile function (used for Port BCs) was "
59 "defined. Either remove the profile function parameters, or set your BC to Port mode!");
60 }
61}
62
63Real
65{
66 // Initialize E components
67 std::complex<double> field_0(0, 0);
68 std::complex<double> field_1(0, 0);
69 std::complex<double> field_2(0, 0);
70
71 // Create E and ncrossE for residual based on component parameter
72 if (_component == EM::REAL)
73 {
74 field_0.real(_u[_qp](0));
75 field_0.imag(_coupled_val[_qp](0));
76
77 field_1.real(_u[_qp](1));
78 field_1.imag(_coupled_val[_qp](1));
79
80 field_2.real(_u[_qp](2));
81 field_2.imag(_coupled_val[_qp](2));
82 }
83 else
84 {
85 field_0.real(_coupled_val[_qp](0));
86 field_0.imag(_u[_qp](0));
87
88 field_1.real(_coupled_val[_qp](1));
89 field_1.imag(_u[_qp](1));
90
91 field_2.real(_coupled_val[_qp](2));
92 field_2.imag(_u[_qp](2));
93 }
94 VectorValue<std::complex<double>> field(field_0, field_1, field_2);
95
96 // Initialize proper zero defaults for the case when real and imag incoming functions are not set
97 VectorValue<std::complex<double>> field_inc(std::complex<double>(0.0, 0.0),
98 std::complex<double>(0.0, 0.0),
99 std::complex<double>(0.0, 0.0));
100 VectorValue<std::complex<double>> curl_inc(std::complex<double>(0.0, 0.0),
101 std::complex<double>(0.0, 0.0),
102 std::complex<double>(0.0, 0.0));
103
110 {
111 // Creating vector, curl for field_inc before residual and Jacobian contributions
112 RealVectorValue inc_real_value = _inc_real.vectorValue(_t, _q_point[_qp]);
113 RealVectorValue inc_imag_value = _inc_imag.vectorValue(_t, _q_point[_qp]);
114 RealVectorValue inc_real_curl = _inc_real.curl(_t, _q_point[_qp]);
115 RealVectorValue inc_imag_curl = _inc_imag.curl(_t, _q_point[_qp]);
116
117 std::complex<double> field_inc_0(inc_real_value(0), inc_imag_value(0));
118 std::complex<double> field_inc_1(inc_real_value(1), inc_imag_value(1));
119 std::complex<double> field_inc_2(inc_real_value(2), inc_imag_value(2));
120 field_inc = VectorValue<std::complex<double>>(field_inc_0, field_inc_1, field_inc_2);
121
122 std::complex<double> curl_inc_0(inc_real_curl(0), inc_imag_curl(0));
123 std::complex<double> curl_inc_1(inc_real_curl(1), inc_imag_curl(1));
124 std::complex<double> curl_inc_2(inc_real_curl(2), inc_imag_curl(2));
125 curl_inc = VectorValue<std::complex<double>>(curl_inc_0, curl_inc_1, curl_inc_2);
126 }
127
128 // Do some error checking
129 mooseAssert(_beta.value(_t, _q_point[_qp]) > 0,
130 "Wave number expected to be positive, calculated to be "
131 << _beta.value(_t, _q_point[_qp]));
132
133 std::complex<double> u_inc_dot_test = 0.0;
134 switch (_mode)
135 {
136 case EM::PORT:
137 // Calculate incoming wave contribution to BC residual
138 u_inc_dot_test = _test[_i][_qp].cross(_normals[_qp]) * curl_inc +
140 (_test[_i][_qp].cross(_normals[_qp]) * _normals[_qp].cross(field_inc));
141 break;
142 case EM::ABSORBING:
143 break;
144 }
145
146 // Calculate solution field contribution to BC residual (first order version)
147 std::complex<double> p_dot_test = EM::j * _beta.value(_t, _q_point[_qp]) *
148 _test[_i][_qp].cross(_normals[_qp]) *
149 _normals[_qp].cross(field);
150
151 std::complex<double> diff = u_inc_dot_test - p_dot_test;
152 Real res = 0.0;
153 switch (_component)
154 {
155 case EM::REAL:
156 res = diff.real();
157 break;
158 case EM::IMAGINARY:
159 res = diff.imag();
160 break;
161 }
162 return res;
163}
164
165Real
167{
168 return 0.0;
169}
170
171Real
173{
174 Real off_diag_jac = _beta.value(_t, _q_point[_qp]) * _test[_i][_qp].cross(_normals[_qp]) *
175 _normals[_qp].cross(_phi[_j][_qp]);
176
177 if (_component == EM::REAL && jvar == _coupled_var_num)
178 return off_diag_jac;
179 else if (_component == EM::IMAGINARY && jvar == _coupled_var_num)
180 return -off_diag_jac;
181 else
182 return 0.0;
183}
registerMooseObject("ElectromagneticsApp", VectorEMRobinBC)
virtual RealVectorValue curl(Real t, const Point &p) const
virtual Real value(Real t, const Point &p) const
virtual RealVectorValue vectorValue(Real t, const Point &p) const
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
unsigned int _qp
unsigned int _i
unsigned int _j
const MooseArray< Point > & _q_point
void mooseError(Args &&... args) const
const std::string & _name
First order Robin-style Absorbing/Port boundary condition for vector nonlinear variables.
VectorEMRobinBC(const InputParameters &parameters)
const MooseEnum _mode
Mode of operation (absorbing or port)
static InputParameters validParams()
const Function & _inc_real
Real incoming field vector.
virtual Real computeQpResidual() override
const Function & _inc_imag
Imaginary incoming field vector.
const VectorVariableValue & _coupled_val
Coupled field vector variable.
virtual Real computeQpJacobian() override
unsigned int _coupled_var_num
Coupled field vector variable id.
const bool _real_incoming_was_set
Boolean marking whether real component of the incoming wave was set by the user.
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const MooseEnum _component
Variable field component (real or imaginary)
const Function & _beta
Scalar waveguide propagation constant.
const bool _imag_incoming_was_set
Boolean marking whether imaginary component of the incoming wave was set by the user.
static InputParameters validParams()
const MooseArray< Point > & _normals
const VectorVariablePhiValue & _phi
const VectorVariableTestValue & _test
const VectorVariableValue & _u
@ ABSORBING
Case when the boundary is configured to absorb impinging electromagnetic radiation.
@ PORT
Case when the boundary is configured to both absorb impinging electromagnetic radiation and launch an...
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")