OpenBEM
Open-source framework for electromagnetic simulation with the boundary element method.
Loading...
Searching...
No Matches
single_layer.tpp
Go to the documentation of this file.
1// OpenBEM - Copyright (C) 2026 Shashwat Sharma
2
3// This file is part of OpenBEM.
4
5// OpenBEM is free software: you can redistribute it and/or modify it under the terms of the
6// GNU General Public License as published by the Free Software Foundation, either version 3
7// of the License, or (at your option) any later version.
8
9// You should have received a copy of the GNU General Public License along with OpenBEM.
10// If not, see <https://www.gnu.org/licenses/>.
11
12
18#ifndef BEM_RWG_OPS_SINGLE_LAYER_I
19#define BEM_RWG_OPS_SINGLE_LAYER_I
20
21#include "types.hpp"
22#include "constants.hpp"
26
27
28namespace bem::rwg
29{
30
31template <typename ObsIntegratorType>
33 const Complex k,
34 const Triangle<3>& obs_tri,
35 const Triangle<3>& src_tri
36 )
37{
40 transform_coordinates(obs_tri_local, src_tri_local, obs_tri, src_tri);
41
42 obs_integrator_.set_compute_terms(false, true, false, false);
43 const ObsResult obs_result = obs_integrator_.integrate(k, obs_tri_local, src_tri_local);
44
45 return assemble(k, obs_tri_local, src_tri_local.to_3d(), obs_result);
46};
47
48
49template <typename ObsIntegratorType>
51 const Complex k,
52 const Triangle<3>& obs_tri,
53 const Triangle<3>& src_tri,
55 )
56{
58
60
61 // source triangle edges
62 for (uint8_t jj = 0; jj < 3; ++jj)
63 {
64 Float xn = src_tri.v((jj + 2) % 3)[0];
65 Float yn = src_tri.v((jj + 2) % 3)[1];
66
67 // observer triangle edges
68 for (uint8_t ii = 0; ii < 3; ++ii)
69 {
70 Float xm = obs_tri.v((ii + 2) % 3)[0];
71 Float ym = obs_tri.v((ii + 2) % 3)[1];
72
73 result(ii, jj) = (xm * xn + ym * yn) * I[0]
74 - xm * I[1] - ym * I[2]
75 - xn * I[3] - yn * I[4]
76 + I[6] + I[10];
77 }
78 }
79
80 result.array() *= (
82 ).array();
83
84 return result;
85};
86
87
88template <typename ObsIntegratorType>
90 const Complex k,
91 const Triangle<3>& obs_tri,
92 const Triangle<3>& src_tri
93 )
94{
97 transform_coordinates(obs_tri_local, src_tri_local, obs_tri, src_tri);
98
99 obs_integrator_.set_compute_terms(false, true, false, false);
100 const ObsResult obs_result = obs_integrator_.integrate(k, obs_tri_local, src_tri_local);
101
102 return assemble(k, obs_tri_local, src_tri_local.to_3d(), obs_result);
103};
104
105
106template <typename ObsIntegratorType>
108 const Complex k,
109 const Triangle<3>& obs_tri,
110 const Triangle<3>& src_tri,
111 const ObsResult& obs_result
112 )
113{
115
117
118 Float nx = obs_tri.normal()[0];
119 Float ny = obs_tri.normal()[1];
120 Float nz = obs_tri.normal()[2];
121
122 // source triangle edges
123 for (uint8_t jj = 0; jj < 3; ++jj)
124 {
125 Float xn = src_tri.v((jj + 2) % 3)[0];
126 Float yn = src_tri.v((jj + 2) % 3)[1];
127
128 // observer triangle edges
129 for (uint8_t ii = 0; ii < 3; ++ii)
130 {
131 Float xm = obs_tri.v((ii + 2) % 3)[0];
132 Float ym = obs_tri.v((ii + 2) % 3)[1];
133 Float zm = obs_tri.v((ii + 2) % 3)[2];
134
135 result(ii, jj) = -(
136 (ny * zm - nz * ym) * I[1]
137 + (nz * xm - nx * zm) * I[2]
138 + (nx * zm * yn - ny* zm * xn + nz * ym * xn - nz * xm * yn) * I[0]
139 + nz * yn * I[3] - nz * xn * I[4] + (ny * xn - nx * yn) * I[5]
140 + nz * I[7] - nz * I[9] - ny * I[8] + nx * I[11]
141 );
142 }
143 }
144
145 result.array() *= (
147 ).array();
148
149 return result;
150};
151
152
153template <typename ObsIntegratorType>
155 const Complex k,
157 const Triangle<3>& src_tri
158 )
159{
162 transform_coordinates(obs_tri_local, src_tri_local, obs_tri, src_tri);
163
164 obs_integrator_.set_compute_terms(true, false, false, false);
165 const ObsResult obs_result = obs_integrator_.integrate(k, obs_tri_local, src_tri_local);
166
167 return assemble(k, obs_tri_local, src_tri_local.to_3d(), obs_result);
168};
169
170
171template <typename ObsIntegratorType>
186
187
188template <typename ObsIntegratorType>
190 const Complex k,
191 const Triangle<3>& obs_tri,
192 const Triangle<3>& src_tri
193 )
194{
197 transform_coordinates(obs_tri_local, src_tri_local, obs_tri, src_tri);
198
199 obs_integrator_.set_compute_terms(false, false, true, false);
200 const ObsResult obs_result = obs_integrator_.integrate(k, obs_tri_local, src_tri_local);
201
202 return assemble(k, obs_tri_local, src_tri_local.to_3d(), obs_result);
203};
204
205
206template <typename ObsIntegratorType>
208 const Complex k,
209 const Triangle<3>& obs_tri,
210 const Triangle<3>& src_tri,
211 const ObsResult& obs_result
212 )
213{
215
217 return result;
218
219 const EigRowVecN<Complex, 9>& I = obs_result.grad_g;
220
221 Float nx = obs_tri.normal()[0];
222 Float ny = obs_tri.normal()[1];
223 Float nz = obs_tri.normal()[2];
224
225 // observer triangle edges
226 for (uint8_t ii = 0; ii < 3; ++ii)
228 Float xm = obs_tri.v((ii + 2) % 3)[0];
229 Float ym = obs_tri.v((ii + 2) % 3)[1];
230 Float zm = obs_tri.v((ii + 2) % 3)[2];
231
232 result[ii] = -(
233 (zm * ny - ym * nz) * I[0] + (xm * nz - zm * nx) * I[3]
234 + nz * I[1] - ny * I[2] - nz * I[4] + nx * I[5]
235 + (ym * nx - ny * xm) * I[6]
236 + ny * I[7] - nx * I[8]
237 );
238
239 // result[ii] = -(-nx * ((I[3] * zm - I[6] * ym) - (I[5] - I[8]))
240 // - ny * ((I[6] * xm - I[0] * zm) - (I[7] - I[2]))
241 // - nz * ((I[0] * ym - I[3] * xm) - (I[1] - I[4])));
243
245
246 return result;
247
248};
249
250
251template <typename ObsIntegratorType>
253 const Complex k,
254 const Triangle<3>& obs_tri,
255 const Triangle<3>& src_tri
256 )
257{
258 EigMatMN<Complex, 3, 3> result = op_g_.compute(k, obs_tri, src_tri);
259 Complex hessg_term = op_hessg_.compute(k, obs_tri, src_tri)[0] / k / k;
260 result -= hessg_term * obs_tri.edge_polarities().transpose() * src_tri.edge_polarities();
261 return result;
262};
263
264
265template <typename ObsIntegratorType>
267 const Complex k,
268 const Triangle<3>& obs_tri,
269 const Triangle<3>& src_tri
270 )
271{
272 EigMatMN<Complex, 3, 3> result = op_g_.compute(k, obs_tri, src_tri);
273 EigMatMN<Complex, 3, 1> hessg_term = op_hessg_.compute(k, obs_tri, src_tri) / k / k;
274 result += hessg_term * src_tri.edge_polarities();
275 return result;
276};
277
278}
279
280#endif
Geometry operations class.
static Float normalization(const Triangle< 3 > &tri)
Defines the normalization factor for the pulse function associated with a given triangle.
EigMatMN< Complex, 3, 1 > compute(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri) override
Computes operator values for the given observation and source triangles.
EigMatMN< Complex, 3, 1 > assemble(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri, const ObsResult &obs_result)
Assembles the computed integrals into the final operator values.
EigMatMN< Complex, 3, 3 > compute(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri) override
Computes operator values for the given observation and source triangles.
EigMatMN< Complex, 3, 3 > assemble(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri, const ObsResult &obs_result)
Assembles the computed integrals into the final operator values.
EigMatMN< Complex, 3, 3 > compute(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri) override
Computes operator values for the given observation and source triangles.
static EigRowVecN< Float, 3 > normalization(const Triangle< 3 > &tri)
Defines the normalization factor for each RWG function associated with a given triangle.
EigMatMN< Complex, 1, 1 > assemble(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri, const ObsResult &obs_result)
Assembles the computed integrals into the final operator values.
EigMatMN< Complex, 1, 1 > compute(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri) override
Computes operator values for the given observation and source triangles.
EigMatMN< Complex, 3, 3 > compute(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri) override
Computes operator values for the given observation and source triangles.
EigMatMN< Complex, 3, 3 > assemble(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri, const ObsResult &obs_result)
Assembles the computed integrals into the final operator values.
EigMatMN< Complex, 3, 3 > compute(const Complex k, const Triangle< 3 > &obs_tri, const Triangle< 3 > &src_tri) override
Computes operator values for the given observation and source triangles.
Eigen::Matrix< T, M, N > EigMatMN
Fixed-size matrix with M rows and N columns containing type T.
Definition types.hpp:70
double Float
Floating point number.
Definition types.hpp:47
std::complex< Float > Complex
Complex floating point number.
Definition types.hpp:51
Eigen::Matrix< T, N, 1 > EigColVecN
Fixed-size column vector of size N containing type T.
Definition types.hpp:86
Namespace for RWG-based BEM functionality.
Data structure to hold the results of integration over the observation triangle.
Definition base.hpp:37