Discontinuous Galerkin Library
#include "dg/algorithm.h"
filter.h
Go to the documentation of this file.
1#pragma once
2#include "dg/functors.h"
4
9namespace dg
10{
11
12namespace create
13{
14
39template<class UnaryOp, class real_type>
41{
44 Operator<real_type> filter( dlt.n(), 0);
45 for( unsigned i=0; i<dlt.n(); i++)
46 filter(i,i) = op( i);
47 filter = backward*filter*forward;
48 return filter;
49}
50
51} //namespace create
52
54namespace detail{
55
56template<class real_type>
57DG_DEVICE void pix_sort( real_type& a, real_type& b)
58{
59 if( a > b) // swap
60 {
61 real_type tmp = a;
62 a = b;
63 b = tmp;
64 }
65}
66
67template<class real_type>
68DG_DEVICE real_type median3( real_type* p)
69{
70 pix_sort(p[0],p[1]) ; pix_sort(p[1],p[2]) ; pix_sort(p[0],p[1]) ;
71 return (p[1]) ;
72}
73
74template<class real_type>
75DG_DEVICE real_type median5( real_type* p)
76{
77 pix_sort(p[0],p[1]) ; pix_sort(p[3],p[4]) ; pix_sort(p[0],p[3]) ;
78 pix_sort(p[1],p[4]) ; pix_sort(p[1],p[2]) ; pix_sort(p[2],p[3]) ;
79 pix_sort(p[1],p[2]) ; return (p[2]) ;
80}
81
82template<class real_type>
83DG_DEVICE real_type median9( real_type* p)
84{
85 pix_sort(p[1], p[2]) ; pix_sort(p[4], p[5]) ; pix_sort(p[7], p[8]) ;
86 pix_sort(p[0], p[1]) ; pix_sort(p[3], p[4]) ; pix_sort(p[6], p[7]) ;
87 pix_sort(p[1], p[2]) ; pix_sort(p[4], p[5]) ; pix_sort(p[7], p[8]) ;
88 pix_sort(p[0], p[3]) ; pix_sort(p[5], p[8]) ; pix_sort(p[4], p[7]) ;
89 pix_sort(p[3], p[6]) ; pix_sort(p[1], p[4]) ; pix_sort(p[2], p[5]) ;
90 pix_sort(p[4], p[7]) ; pix_sort(p[4], p[2]) ; pix_sort(p[6], p[4]) ;
91 pix_sort(p[4], p[2]) ; return (p[4]) ;
92}
93
94template<class real_type, class Functor>
95DG_DEVICE real_type median( unsigned i, const int* row_offsets,
96 const int* column_indices, Functor f, const real_type* x )
97{
98 int n = row_offsets[i+1]-row_offsets[i];
99 if( n == 3)
100 {
101 real_type p[3];
102 int k = row_offsets[i];
103 for( int l = 0; l<3; l++)
104 p[l] = f(x[column_indices[k+l]]);
105 return detail::median3( p);
106 }
107 if ( n == 5)
108 {
109 real_type p[5];
110 int k = row_offsets[i];
111 for( int l = 0; l<5; l++)
112 p[l] = f(x[column_indices[k+l]]);
113 return detail::median5(p);
114 }
115 if( n == 9)
116 {
117 real_type p[9];
118 int k = row_offsets[i];
119 for( int l = 0; l<9; l++)
120 p[l] = f(x[column_indices[k+l]]);
121 return detail::median9( p);
122
123 }
124 int less, greater, equal;
125 real_type min, max, guess, maxltguess, mingtguess;
126
127 min = max = f(x[column_indices[row_offsets[i]]]) ;
128 for (int k=row_offsets[i]+1 ; k<row_offsets[i+1] ; k++) {
129 if (f(x[column_indices[k]])<min) min=f(x[column_indices[k]]);
130 if (f(x[column_indices[k]])>max) max=f(x[column_indices[k]]);
131 }
132
133 while (1) {
134 guess = (min+max)/2;
135 less = 0; greater = 0; equal = 0;
136 maxltguess = min ;
137 mingtguess = max ;
138 for (int k=row_offsets[i]; k<row_offsets[i+1]; k++) {
139 if (f(x[column_indices[k]])<guess) {
140 less++;
141 if (f(x[column_indices[k]])>maxltguess)
142 maxltguess = f(x[column_indices[k]]) ;
143 } else if (f(x[column_indices[k]])>guess) {
144 greater++;
145 if (f(x[column_indices[k]])<mingtguess)
146 mingtguess = f(x[column_indices[k]]) ;
147 } else equal++;
148 }
149 if (less <= (n+1)/2 && greater <= (n+1)/2) break ;
150 else if (less>greater) max = maxltguess ;
151 else min = mingtguess;
152 }
153 if (less >= (n+1)/2) return maxltguess;
154 else if (less+equal >= (n+1)/2) return guess;
155 else return mingtguess;
156}
157
158}//namespace detail
160
163
174{
175 template<class real_type>
177 void operator()( unsigned i, const int* row_offsets,
178 const int* column_indices, const real_type* values,
179 const real_type* x, real_type* y)
180 {
181 // http://ndevilla.free.fr/median/median/index.html
182 // ignore the values array ...
183 y[i] = detail::median( i, row_offsets, column_indices, []DG_DEVICE(double x){return x;}, x);
184 }
185};
186
187
206template<class real_type>
208{
209 CSRSWMFilter( real_type alpha) : m_alpha( alpha) {}
211 void operator()( unsigned i, const int* row_offsets,
212 const int* column_indices, const real_type* values,
213 const real_type* x, real_type* y)
214 {
215 real_type median = detail::median( i, row_offsets, column_indices,
216 []DG_DEVICE(double x){return x;}, x);
217 real_type amd = detail::median( i, row_offsets, column_indices,
218 [median]DG_DEVICE(double x){return fabs(x-median);}, x);
219
220 if( fabs( x[i] - median) > m_alpha*amd)
221 {
222 y[i] = median;
223 }
224 else
225 y[i] = x[i];
226 }
227 private:
228 real_type m_alpha ;
229};
230
236{
237 template<class real_type>
239 void operator()( unsigned i, const int* row_offsets,
240 const int* column_indices, const real_type* values,
241 const real_type* x, real_type* y)
242 {
243 y[i] = 0;
244 int n = row_offsets[i+1]-row_offsets[i];
245 for( int k=row_offsets[i]; k<row_offsets[i+1]; k++)
246 y[i] += x[column_indices[k]]/(real_type)n;
247 }
248};
254{
255 template<class real_type>
257 void operator()( unsigned i, const int* row_offsets,
258 const int* column_indices, const real_type* values,
259 const real_type* x, real_type* y)
260 {
261 y[i] = 0;
262 for( int k=row_offsets[i]; k<row_offsets[i+1]; k++)
263 y[i] += x[column_indices[k]]*values[k];
264 }
265};
266
286template<class real_type>
288{
289 CSRSlopeLimiter( real_type mod = (real_type)0) :
290 m_mod(mod) {}
292 void operator()( unsigned i, const int* row_offsets,
293 const int* column_indices, const real_type* values,
294 const real_type* x, real_type* y)
295 {
296 int k = row_offsets[i];
297 int n = (row_offsets[i+1] - row_offsets[i])/3;
298 if( n == 0) //only every n-th thread does something
299 return;
300 for( int u=0; u<n; u++)
301 y[column_indices[k+1*n+u]] = x[column_indices[k+1*n + u]]; // copy input
302 // Transform
303 real_type uM = 0, u0 = 0, uP = 0, u1 = 0;
304 for( int u=0; u<n; u++)
305 {
306 uM += x[column_indices[k+0*n + u]]*fabs(values[k+u]);
307 u0 += x[column_indices[k+1*n + u]]*fabs(values[k+u]);
308 u1 += x[column_indices[k+1*n + u]]*values[k+n+u];
309 uP += x[column_indices[k+2*n + u]]*fabs(values[k+u]);
310 }
311 if( values[k]<0) //DIR boundary condition
312 uM *= -1;
313 if( values[k+2*n]>0) //DIR boundary condition
314 uP *= -1;
315
316 dg::MinMod minmod;
317 if( fabs( u1) <= m_mod)
318 return;
319 real_type m = minmod( u1, uP - u0, u0 - uM);
320 if( m == u1)
321 return;
322 // Else transform back
323 for( int u=0; u<n; u++)
324 y[column_indices[k+1*n+u]] =
325 values[k+2*n]>0 ? u0 - m*values[k+2*n+u] : u0 + m*values[k+2*n+u];
326 }
327 private:
328 real_type m_mod;
329};
330
331
333}//namespace dg
Struct holding coefficients for Discrete Legendre Transformation (DLT) related operations.
Definition: dlt.h:23
const std::vector< real_type > & backward() const
Return backward DLT trafo matrix.
Definition: dlt.h:62
const std::vector< real_type > & forward() const
Return forward DLT trafo matrix.
Definition: dlt.h:55
unsigned n() const
# of polynomial coefficients
Definition: dlt.h:35
A matrix type for fast interpolations/projections.
#define DG_DEVICE
Expands to __host__ __device__ if compiled with nvcc else is empty.
Definition: functions.h:9
@ backward
backward derivative (cell to the left and current cell)
Definition: enums.h:99
@ forward
forward derivative (cell to the right and current cell)
Definition: enums.h:98
@ y
y direction
@ x
x direction
dg::Operator< real_type > modal_filter(UnaryOp op, const DLT< real_type > &dlt)
Create a modal filter block .
Definition: filter.h:40
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Average filter that computes the average of all points in the stencil
Definition: filter.h:236
DG_DEVICE void operator()(unsigned i, const int *row_offsets, const int *column_indices, const real_type *values, const real_type *x, real_type *y)
Definition: filter.h:239
Compute (lower) Median of input numbers.
Definition: filter.h:174
DG_DEVICE void operator()(unsigned i, const int *row_offsets, const int *column_indices, const real_type *values, const real_type *x, real_type *y)
Definition: filter.h:177
Switching median filter.
Definition: filter.h:208
DG_DEVICE void operator()(unsigned i, const int *row_offsets, const int *column_indices, const real_type *values, const real_type *x, real_type *y)
Definition: filter.h:211
CSRSWMFilter(real_type alpha)
Definition: filter.h:209
Generalized slope limiter for dG methods.
Definition: filter.h:288
CSRSlopeLimiter(real_type mod=(real_type) 0)
Definition: filter.h:289
DG_DEVICE void operator()(unsigned i, const int *row_offsets, const int *column_indices, const real_type *values, const real_type *x, real_type *y)
Definition: filter.h:292
Test filter that computes the symv csr matrix-vector product if used.
Definition: filter.h:254
DG_DEVICE void operator()(unsigned i, const int *row_offsets, const int *column_indices, const real_type *values, const real_type *x, real_type *y)
Definition: filter.h:257
Definition: functors.h:297