LoAdSG
helmIntegrator.h
1/**********************************************************************************
2* Author: Christoph Pflaum, Riccarda Scherner-Griesshammer, Tim Rheinfels
3 * Department Informatik Lehrstuhl 10 - Systemsimulation
4 * Friedrich-Alexander Universität Erlangen-Nürnberg
5 *
6*********************************************/
7
8#ifndef INTERATORHELM_H
9#define INTERATORHELM_H
10
11#include <cmath>
12#include <functional>
13#include <limits>
14
15#include "integral.hpp"
16
25template <typename F, size_t N>
27{
28
29 private:
30
35 {
36
37 private:
38
39 std::array<double, N> m_p_left;
40 std::array<double, N> m_p_right;
41 std::array<BasisFunctionType, N> m_u;
42 std::array<BasisFunctionType, N> m_v;
44 double m_gamma;
45
46
47 public:
48
59 inline HelmholtzTerm( const std::array<double, N>& p_left, const std::array<double, N>& p_right,
60 const std::array<BasisFunctionType, N>& u, const std::array<BasisFunctionType, N>& v,
61 const F& variable_coefficient, double gamma )
62 : m_p_left(p_left),
63 m_p_right(p_right),
64 m_u(u),
65 m_v(v),
66 m_variable_coefficient(variable_coefficient),
67 m_gamma(gamma)
68 {
69
70 }
71
79 inline double operator() ( const std::array<double, N>& x ) const
80 {
81
82 double value = 1.0;
83
84 for( size_t i = 0; i < N; ++i )
85 {
86
87 // === Muliply by the first base function ===
88 switch( m_u[i] )
89 {
90 case BasisFunctionType::leftBasis:
91 // p(x) = (x-b)/(a-b)
92 value *= (x[i] - m_p_right[i]) / (m_p_left[i] - m_p_right[i]);
93 break;
94
95 case BasisFunctionType::rightBasis:
96 // p(x) = (x-a)/(b-a)
97 value *= (x[i] - m_p_left[i]) / (m_p_right[i] - m_p_left[i]);
98 break;
99
100 case BasisFunctionType::gradLeftBasis:
101 // p'(x) = 1/(b-a)
102 value /= (m_p_left[i] - m_p_right[i]);
103 break;
104
105 case BasisFunctionType::gradRightBasis:
106 // p'(x) = 1/(a-b)
107 value /= (m_p_right[i] - m_p_left[i]);
108 break;
109 }
110
111 // === Muliply by the second base function ===
112 switch( m_v[i] )
113 {
114 case BasisFunctionType::leftBasis:
115 // p(x) = (x-b)/(a-b)
116 value *= (x[i] - m_p_right[i]) / (m_p_left[i] - m_p_right[i]);
117 break;
118
119 case BasisFunctionType::rightBasis:
120 // p(x) = (x-a)/(b-a)
121 value *= (x[i] - m_p_left[i]) / (m_p_right[i] - m_p_left[i]);
122 break;
123
124 case BasisFunctionType::gradLeftBasis:
125 // p'(x) = 1/(b-a)
126 value /= (m_p_left[i] - m_p_right[i]);
127 break;
128
129 case BasisFunctionType::gradRightBasis:
130 // p'(x) = 1/(a-b)
131 value /= (m_p_right[i] - m_p_left[i]);
132 break;
133 }
134
135 }
136
137 // Evaluate the variable coefficient replacing floating point inf by gamma
138 double c_eval = m_variable_coefficient(x);
139
140 if( (std::abs(c_eval) > m_gamma) || (std::fpclassify(c_eval) == FP_INFINITE ))
141 {
142 c_eval = (std::signbit(c_eval) ? (-m_gamma) : m_gamma);
143 }
144
145 // Mulitply by the variable coefficient
146 value *= c_eval;
147
148 // Return Helmholtz function with variable coefficient evaluated at x
149 return value;
150
151 }
152
153 };
154
155
157 double m_epsilon;
158 size_t m_depth_min;
159 size_t m_depth_max;
160 double m_gamma;
161
162
163 public:
164
174 IntegratorHelm( const F& c, double epsilon, size_t depth_min = 0, size_t depth_max = std::numeric_limits<size_t>::max(), double gamma = std::numeric_limits<double>::max() )
176 m_epsilon(epsilon),
177 m_depth_min(depth_min),
178 m_depth_max(depth_max),
179 m_gamma(gamma)
180 {
181
182 /* Nothing to do here... */
183
184 }
185
196 double stencil_integration(double p_left[N], double p_right[N], BasisFunctionType u[N], BasisFunctionType v[N]) const
197 {
198
199 // Duplicate input data as std::array
200 std::array<double, N> p_left_array;
201 std::array<double, N> p_right_array;
202
203 std::array<BasisFunctionType, N> u_array;
204 std::array<BasisFunctionType, N> v_array;
205
206 for( size_t i = 0; i < N; ++i )
207 {
208
209 p_left_array[i] = p_left[i];
210 p_right_array[i] = p_right[i];
211
212 u_array[i] = u[i];
213 v_array[i] = v[i];
214
215 }
216
217 // Create local helmholtz term
218 HelmholtzTerm ht(p_left_array, p_right_array, u_array, v_array, m_variable_coefficient, m_gamma);
219
220
221 // Integrate
222 return integral<double, HelmholtzTerm, N>( ht, p_left_array, p_right_array, m_epsilon, m_depth_min, m_depth_max, m_gamma );
223
224 }
225
226};
227
228#endif
Class for describing a Helmholtz term.
Definition helmIntegrator.h:35
std::array< double, N > m_p_left
First point spanning the domain.
Definition helmIntegrator.h:39
std::array< BasisFunctionType, N > m_v
Base function tensor for the second d-dimensional base function.
Definition helmIntegrator.h:42
std::array< BasisFunctionType, N > m_u
Base function tensor for the first d-dimensional base function.
Definition helmIntegrator.h:41
double operator()(const std::array< double, N > &x) const
Evaluation operator.
Definition helmIntegrator.h:79
F m_variable_coefficient
Functor providing the variable coefficient.
Definition helmIntegrator.h:43
std::array< double, N > m_p_right
Second point spanning the domain.
Definition helmIntegrator.h:40
HelmholtzTerm(const std::array< double, N > &p_left, const std::array< double, N > &p_right, const std::array< BasisFunctionType, N > &u, const std::array< BasisFunctionType, N > &v, const F &variable_coefficient, double gamma)
Constructor.
Definition helmIntegrator.h:59
double m_gamma
Cutoff parameter for singularities.
Definition helmIntegrator.h:44
Integrator for the Helmholtz operator with variable coefficients.
Definition helmIntegrator.h:27
double stencil_integration(double p_left[N], double p_right[N], BasisFunctionType u[N], BasisFunctionType v[N]) const
Performs the integration of the FEM function defined by p_left, p_right, u and u with the additional ...
Definition helmIntegrator.h:196
size_t m_depth_max
Maximum recursion depth.
Definition helmIntegrator.h:159
double m_gamma
Value to replace infinte values with.
Definition helmIntegrator.h:160
F m_variable_coefficient
The variable coefficient.
Definition helmIntegrator.h:156
double m_epsilon
Refinement criterion on the hierarchical surplus.
Definition helmIntegrator.h:157
IntegratorHelm(const F &c, double epsilon, size_t depth_min=0, size_t depth_max=std::numeric_limits< size_t >::max(), double gamma=std::numeric_limits< double >::max())
Constructor.
Definition helmIntegrator.h:174
size_t m_depth_min
Minimum recursion depth.
Definition helmIntegrator.h:158
Definition interfaceMatrices.h:21