Bembel
 
Loading...
Searching...
No Matches
AugmentedEFIE.hpp
1// This file is part of Bembel, the higher order C++ boundary element library.
2//
3// Copyright (C) 2024 see <http://www.bembel.eu>
4//
5// It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz,
6// M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt,
7// Universitaet Basel, and Universita della Svizzera italiana, Lugano. This
8// source code is subject to the GNU General Public License version 3 and
9// provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further
10// information.
11#ifndef BEMBEL_SRC_AUGMENTEDEFIE_AUGMENTEDEFIE_HPP_
12#define BEMBEL_SRC_AUGMENTEDEFIE_AUGMENTEDEFIE_HPP_
13
14namespace Bembel {
19template <typename MatrixFormat, typename Derived>
21 public:
23 // constructors
25 AugmentedEFIE() {}
27 const Geometry &geometry) {
28 init_AugmentedEFIE(ansatz_space_vector, geometry);
29 }
31 // init_AugmentedEFIE
33 void init_AugmentedEFIE(const AnsatzSpace<Derived> &ansatz_space_vector,
34 const Geometry &geometry) {
35 ansatz_space_vector_ = ansatz_space_vector;
36
37 // Build ansatz spaces
38 ansatz_space_mass_ = AnsatzSpace<MassMatrixScalarDisc>(
39 geometry, ansatz_space_vector.get_refinement_level(),
40 ansatz_space_vector.get_polynomial_degree() - 1);
41
42 ansatz_space_scalar_ = AnsatzSpace<HelmholtzSingleLayerOperator>(
43 geometry, ansatz_space_vector.get_refinement_level(),
44 ansatz_space_vector.get_polynomial_degree() - 1);
45
46 dofs_scalar_ = ansatz_space_scalar_.get_number_of_dofs();
47 dofs_vector_ = ansatz_space_vector_.get_number_of_dofs();
48 return;
49 }
51 // compute
53
56 inline void compute() {
57 system_matrix_ = Eigen::MatrixXcd(dofs_scalar_ + dofs_vector_,
58 dofs_scalar_ + dofs_vector_);
59
61 &system_matrix_, ansatz_space_mass_, ansatz_space_scalar_,
62 ansatz_space_vector_, wavenumber_);
63 return;
64 }
69 const int elements_per_edge =
70 (1 << ansatz_space_vector_.get_refinement_level());
71 // This number contains all degrees of freedom on the edge for the
72 // excitation and three extra ones dedicated to the potential of the voltage
73 // source.
74 const int dofs_excitation =
75 3 +
76 (source.positive_.size() + source.negative_.size()) * elements_per_edge;
77 system_matrix_ =
78 Eigen::MatrixXcd::Zero(dofs_scalar_ + dofs_vector_ + dofs_excitation,
79 dofs_scalar_ + dofs_vector_ + dofs_excitation);
80 excitation_ = Eigen::VectorXcd::Zero(dofs_scalar_);
81
83 &system_matrix_, &excitation_, ansatz_space_mass_, ansatz_space_scalar_,
84 ansatz_space_vector_, wavenumber_, source);
85 return;
86 }
87 void stabilize() {
88 std::function<std::complex<double>(Eigen::Vector3d)> one =
89 [](Eigen::Vector3d in) { return std::complex<double>(1., 0.); };
91 HelmholtzSingleLayerOperator>
92 const_lf(ansatz_space_scalar_);
93 const_lf.get_linear_form().set_function(one);
94 const_lf.compute();
95
96 system_matrix_.bottomRows(dofs_scalar_) *= omega_ *
97 std::complex<double>(0., 1.) *
98 Constants::mu0 * Constants::eps0;
99 system_matrix_.leftCols(dofs_vector_) *=
100 1. / (omega_ * std::complex<double>(0., 1.) * Constants::mu0);
101
102 std::complex<double> eigenvalues_average =
103 system_matrix_.trace() / ((double)system_matrix_.cols());
104
105 Eigen::VectorXcd a = Eigen::VectorXcd::Zero(system_matrix_.cols());
106 a.bottomRows(dofs_scalar_) = const_lf.get_discrete_linear_form();
107
108 system_matrix_ = system_matrix_ - eigenvalues_average * a * a.transpose();
109 }
111 // setters
113
116 void set_wavenumber(std::complex<double> wavenumber) {
117 wavenumber_ = wavenumber;
118 }
119 void set_omega(double omega) { omega_ = omega; }
121 // getters
123 const MatrixFormat &get_system_matrix() const { return system_matrix_; }
127 const std::complex<double> get_wavenumber() { return wavenumber_; }
131 const int get_dofs_vector() { return dofs_vector_; }
135 const int get_dofs_scalar() { return dofs_scalar_; }
139 const Eigen::VectorXcd get_excitation() { return excitation_; }
144 return ansatz_space_scalar_;
145 }
146 const AnsatzSpace<MassMatrixScalarDisc> get_ansatz_space_mass() {
147 return ansatz_space_mass_;
148 }
150 // private member variables
152 private:
153 MatrixFormat system_matrix_;
154 Eigen::VectorXcd excitation_;
155
156 AnsatzSpace<MassMatrixScalarDisc> ansatz_space_mass_;
158 AnsatzSpace<InductanceMatrix> ansatz_space_vector_;
159
160 int dofs_scalar_;
161 int dofs_vector_;
162 double omega_;
163 std::complex<double> wavenumber_;
164};
165
166} // namespace Bembel
167#endif // BEMBEL_SRC_AUGMENTEDEFIE_AUGMENTEDEFIE_HPP_
The AnsatzSpace is the class that handles the assembly of the discrete basis.
This class handles the assembly and storage of the system matrix.
void compute()
Assembles the system matrix without voltage source excitation.
const int get_dofs_vector()
Return number of degrees of freedom for the current.
void compute(VoltageSource source)
Assembles the system matrix with voltage source excitation.
const int get_dofs_scalar()
Return number of degrees of freedom for the potential.
const std::complex< double > get_wavenumber()
Return wave number.
const Eigen::VectorXcd get_excitation()
Debug output for the excitation.
const AnsatzSpace< HelmholtzSingleLayerOperator > get_ansatz_space_scalar()
Debug output for the excitation.
void set_wavenumber(std::complex< double > wavenumber)
Set wave number.
this class wraps a GeometryVector and provides some basic functionality, like reading Geometry files
Definition Geometry.hpp:20
Routines for the evalutation of pointwise errors.
constexpr int getFunctionSpaceOutputDimension()