FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
unit_filter_blocked_generic.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7#ifndef KERNEL_LAFEM_ARCH_UNIT_FILTER_BLOCKED_GENERIC_HPP
8#define KERNEL_LAFEM_ARCH_UNIT_FILTER_BLOCKED_GENERIC_HPP 1
9
10#ifndef KERNEL_LAFEM_ARCH_UNIT_FILTER_BLOCKED_HPP
11#error "Do not include this implementation-only header file directly!"
12#endif
13
14#include <kernel/util/math.hpp>
15
17namespace FEAT
18{
19 namespace LAFEM
20 {
21 namespace Arch
22 {
23 template <typename DT_, typename IT_>
24 void UnitFilterBlocked::filter_rhs_generic(DT_ * v, int block_size, const DT_ * const sv_elements, const IT_ * const sv_indices, const Index ue, bool ign_nans)
25 {
26 if(ign_nans)
27 {
28 FEAT_PRAGMA_OMP(parallel for)
29 for(Index i = 0; i < ue; ++i)
30 {
31 for(int j = 0 ; j < block_size ; ++j)
32 {
33 if(!Math::isnan(sv_elements[block_size * i + Index(j)]))
34 v[block_size * sv_indices[i] + j] = sv_elements[block_size * i + Index(j)];
35 }
36 }
37 }
38 else
39 {
40 FEAT_PRAGMA_OMP(parallel for)
41 for(Index i = 0; i < ue; ++i)
42 {
43 for(int j = 0 ; j < block_size ; ++j)
44 {
45 v[block_size * sv_indices[i] + j] = sv_elements[block_size * i + Index(j)];
46 }
47 }
48 }
49 }
50
51 template <typename DT_, typename IT_>
52 void UnitFilterBlocked::filter_def_generic(DT_ * v, int block_size, const DT_ * const sv_elements, const IT_ * const sv_indices, const Index ue, bool ign_nans)
53 {
54 if(ign_nans)
55 {
56 FEAT_PRAGMA_OMP(parallel for)
57 for(Index i = 0; i < ue; ++i)
58 {
59 for(int j = 0 ; j < block_size ; ++j)
60 {
61 if(!Math::isnan(sv_elements[block_size * i + Index(j)]))
62 v[block_size * sv_indices[i] + j] = DT_(0);
63 }
64 }
65 }
66 else
67 {
68 FEAT_PRAGMA_OMP(parallel for)
69 for(Index i = 0; i < ue; ++i)
70 {
71 for(int j = 0 ; j < block_size ; ++j)
72 v[block_size * sv_indices[i] + j] = DT_(0);
73 }
74 }
75 }
76
77 template<typename DT_, typename IT_>
78 void UnitFilterBlocked::filter_unit_mat_generic(DT_* mat, const IT_* const row_ptr, const IT_* const col_idx, int block_height, int block_width,
79 const DT_ * const sv_elements, const IT_ * const sv_indices, const Index ue, bool ign_nans)
80 {
81 FEAT_PRAGMA_OMP(parallel for)
82 for(Index i = 0; i < ue; ++i)
83 {
84 const IT_ ix(sv_indices[i]);
85 const DT_* const vx(&sv_elements[i*block_height]);
86
87 // replace by unit row
88 for(IT_ j(row_ptr[ix]); j < row_ptr[ix + 1]; ++j)
89 {
90 // loop over rows in the block
91 for(int k(0); k < block_height; ++k)
92 {
93 // possibly skip row if filter value is NaN
94 if(ign_nans && Math::isnan(vx[k]))
95 continue;
96 for(int l(0); l < block_width; ++l)
97 mat[j*block_height*block_width + k*block_width + l] = DT_(0);
98 if((col_idx[j] == ix) && (k < block_width))
99 mat[j*block_height*block_width + k*block_width + k] = DT_(1);
100 }
101 }
102 }
103 }
104
105 template<typename DT_, typename IT_>
106 void UnitFilterBlocked::filter_offdiag_row_mat_generic(DT_* mat, const IT_* const row_ptr, int block_height, int block_width,
107 const DT_ * const sv_elements, const IT_ * const sv_indices, const Index ue, bool ign_nans)
108 {
109 FEAT_PRAGMA_OMP(parallel for)
110 for(Index i = 0; i < ue; ++i)
111 {
112 const IT_ ix(sv_indices[i]);
113 const DT_* const vx(&sv_elements[i*block_height]);
114
115 // replace by unit row
116 for(IT_ j(row_ptr[ix]); j < row_ptr[ix + 1]; ++j)
117 {
118 // loop over rows in the block
119 for(int k(0); k < block_height; ++k)
120 {
121 // possibly skip row if filter value is NaN
122 if(ign_nans && Math::isnan(vx[k]))
123 continue;
124 for(int l(0); l < block_width; ++l)
125 mat[j*block_height*block_width + k*block_width + l] = DT_(0);
126 }
127 }
128 }
129 }
130
131 template<typename DT_, typename IT_>
132 void UnitFilterBlocked::filter_weak_matrix_rows_generic(DT_* mat_a, const DT_ * const mat_m, const IT_* const row_ptr, int block_height, int block_width,
133 const DT_ * const sv_elements, const IT_ * const sv_indices, const Index ue)
134 {
135 FEAT_PRAGMA_OMP(parallel for)
136 for(Index i = 0; i < ue; ++i)
137 {
138 const IT_ ix(sv_indices[i]);
139 const DT_* const vx(&sv_elements[i*block_height]);
140
141 // replace by unit row
142 for(IT_ j(row_ptr[ix]); j < row_ptr[ix + 1]; ++j)
143 {
144 // loop over rows in the block
145 for(int k(0); k < block_height; ++k)
146 {
147 for(int l(0); l < block_width; ++l)
148 {
149 mat_a[j*block_height*block_width + k*block_width + l] = vx[k] * mat_m[j*block_height*block_width + k*block_width + l];
150 }
151 }
152 }
153 }
154 }
155
156 } // namespace Arch
157 } // namespace LAFEM
158} // namespace FEAT
160
161#endif // KERNEL_LAFEM_ARCH_UNIT_FILTER_BLOCKED_GENERIC_HPP
bool isnan(T_ x)
Checks whether a value is Not-A-Number.
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.