UCFD_SPARSE  v1.1
Documentation
Loading...
Searching...
No Matches
precon.c
Go to the documentation of this file.
1
25#include "precon.h"
26#include "inverse.h"
27#include <stdlib.h>
28#include <omp.h>
29
30#define blkdim BLOCK*BLOCK
31
36 int *row_ptr, int *col_ind, int *diag_ind, double *nnz_data)
37{
38 int idx, kdx, ck, row, col, ele;
39 int st, ed, jed, kk, kst, ked, jj, iwj;
40 double v, Aik[BLOCK][BLOCK];
41
42 for (idx = 0; idx < bn; idx++)
43 {
44 st = row_ptr[idx];
45 ed = diag_ind[idx];
46 jed = row_ptr[idx+1];
47
48 // kdx : A[i,k]
49 // kk : A[k,k]
50 for (kdx = st; kdx < ed; kdx++)
51 {
52 ck = col_ind[kdx];
53 kk = diag_ind[ck];
54 kst = row_ptr[ck];
55 ked = row_ptr[ck+1];
56
57 // A[i,k] := A[i,k] @ inv(A[k,k])
58 lusubmattrans(&nnz_data[kk*blkdim], &nnz_data[kdx*blkdim]);
59 // memcpy(Aik, &nnz_data[kdx*blkdim], sizeof(double)*BLOCK);
60 for (row=0; row<BLOCK; row++) {
61 for (col=0; col<BLOCK; col++)
62 Aik[row][col] = nnz_data[kdx*blkdim+row*BLOCK+col];
63 }
64
65 // Prepare iw
66 for (jj=kst; jj<ked; jj++) iw[col_ind[jj]] = jj;
67
68 // j iteration
69 for (jj=kdx+1; jj<jed; jj++) {
70 iwj = iw[col_ind[jj]];
71
72 if (iwj != 0) {
73 // nnz_data[jj] -= Aik * nnz_data[iwj]
74 for (row=0; row<BLOCK; row++) {
75 for (col=0; col<BLOCK; col++) {
76 v = 0.0;
77 for (ele=0; ele<BLOCK; ele++)
78 v += Aik[row][ele] * nnz_data[iwj*blkdim+ele*BLOCK+col];
79 nnz_data[jj*blkdim+row*BLOCK+col] -= v;
80 }
81 }
82 }
83 }
84
85 // Clean iw
86 for (jj=kst; jj<ked; jj++) iw[col_ind[jj]] = 0;
87 }
88 // Inverse current row diagonal matrix
89 ludcmp(&nnz_data[ed*blkdim]);
90 }
91
93}
94
95
100void bilu_psolve(int bn, int *row_ptr,
101 int *col_ind, int *diag_ind, double *nnz_data, double *b)
102{
103 int idx, jdx, kdx, row, col;
104 int dd, st, ed, cind;
105 double v, arr[BLOCK];
106
107 // Forward substitution
108 for (idx = 0; idx < bn; idx++)
109 {
110 dd = diag_ind[idx];
111 st = row_ptr[idx];
112
113 // Initialize arr
114 for (kdx = 0; kdx < BLOCK; kdx++)
115 arr[kdx] = b[kdx + idx * BLOCK];
116
117 for (jdx = st; jdx < dd; jdx++)
118 {
119 cind = col_ind[jdx];
120
121 for (row = 0; row < BLOCK; row++)
122 {
123 v = 0.0;
124 for (col = 0; col < BLOCK; col++)
125 v += nnz_data[col + row * BLOCK + jdx * blkdim] * b[col + cind * BLOCK];
126 arr[row] -= v;
127 }
128 }
129
130 for (kdx = 0; kdx < BLOCK; kdx++)
131 b[kdx + idx * BLOCK] = arr[kdx];
132 }
133
134 // Backward substitution
135 for (idx = bn - 1; idx > -1; idx--)
136 {
137 dd = diag_ind[idx];
138 ed = row_ptr[idx + 1];
139
140 // Initialize
141 for (kdx = 0; kdx < BLOCK; kdx++)
142 arr[kdx] = b[kdx + idx * BLOCK];
143
144 for (jdx = dd + 1; jdx < ed; jdx++)
145 {
146 cind = col_ind[jdx];
147
148 for (row = 0; row < BLOCK; row++)
149 {
150 v = 0.0;
151 for (col = 0; col < BLOCK; col++)
152 v += nnz_data[col + row * BLOCK + jdx * blkdim] * b[col + cind * BLOCK];
153 arr[row] -= v;
154 }
155 }
156
157 // LU substitution for vector
158 lusub(&nnz_data[dd*blkdim], arr);
159 for (row=0; row<BLOCK; row++) b[idx*BLOCK+row] = arr[row];
160 }
161}
162
163
167ucfd_status_t lusgs_prepare(int bn, int *diag_ind, double *nnz_data)
168{
169 int idx, didx;
170
171 // Get diagonal block and store reverse
172 // Parallel computation available (Only diagonal matrices are used)
173 #pragma omp parallel for private(didx)
174 for (idx = 0; idx < bn; idx++)
175 {
176 didx = diag_ind[idx];
177 ludcmp(&nnz_data[didx * blkdim]);
178 }
179
180 return UCFD_STATUS_SUCCESS;
181}
182
187void lusgs_psolve(int bn, int *row_ptr,
188 int *col_ind, int *diag_ind, double *nnz_data, double *b)
189{
190 int idx, jdx, kdx, row, col;
191 int dd, st, ed, cind;
192 double v, arr[BLOCK];
193
194 // Forward sweep : (D+L)x' = b -> x' = inv(D) * (b-Lx')
195 for (idx = 0; idx < bn; idx++)
196 {
197 dd = diag_ind[idx];
198 st = row_ptr[idx];
199
200 // arr := b
201 for (kdx = 0; kdx < BLOCK; kdx++)
202 arr[kdx] = b[kdx + idx * BLOCK];
203
204 // arr := b - Lx'
205 for (jdx = st; jdx < dd; jdx++)
206 {
207 cind = col_ind[jdx];
208 for (row = 0; row < BLOCK; row++)
209 {
210 v = 0.0;
211 for (col = 0; col < BLOCK; col++)
212 v += nnz_data[col + row * BLOCK + jdx * blkdim] * b[col + cind * BLOCK];
213 arr[row] -= v;
214 }
215 }
216
217 // x' := inv(D) * (b-Lx') = inv(D) * arr
218 lusub(&nnz_data[dd * blkdim], arr);
219 for (kdx = 0; kdx < BLOCK; kdx++)
220 b[kdx + idx * BLOCK] = arr[kdx];
221 }
222
223 // Backward sweep : (D+U)x = Dx' -> x = x' - inv(D) * Ux
224 for (idx = bn - 1; idx > -1; idx--)
225 {
226 dd = diag_ind[idx];
227 ed = row_ptr[idx + 1];
228
229 // Initialize
230 for (kdx = 0; kdx < BLOCK; kdx++)
231 arr[kdx] = 0.0;
232
233 // arr := Ux
234 for (jdx = dd + 1; jdx < ed; jdx++)
235 {
236 cind = col_ind[jdx];
237 for (row = 0; row < BLOCK; row++)
238 {
239 v = 0.0;
240 for (col = 0; col < BLOCK; col++)
241 v += nnz_data[col + row * BLOCK + jdx * blkdim] * b[col + cind * BLOCK];
242 arr[row] += v;
243 }
244 }
245
246 // arr := inv(D) Ux
247 lusub(&nnz_data[dd * blkdim], arr);
248
249 // b := b - inv(D) Ux
250 for (kdx = 0; kdx < BLOCK; kdx++)
251 b[kdx + idx * BLOCK] -= arr[kdx];
252 }
253}
254
255void none_psolve(int bn, int *row_ptr,
256 int *col_ind, int *diag_ind, double *nnz_data, double *b) {};
void lusub(UCFD_FLOAT *LU, UCFD_FLOAT *b)
Forward/Backward substitution function.
Definition: inverse.c:75
void lusubmattrans(UCFD_FLOAT *LU, UCFD_FLOAT *B)
Forward/Backward substitution for transposed matrix.
Definition: inverse.c:105
void ludcmp(UCFD_FLOAT *A)
LU Decomposition function.
Definition: inverse.c:37
ucfd_status_t bilu_prepare(int bn, int *iw, int *row_ptr, int *col_ind, int *diag_ind, double *nnz_data)
Block fill-in Incomplete LU preconditioner for BSR matrix format.
Definition: precon.c:35
void none_psolve(int bn, int *row_ptr, int *col_ind, int *diag_ind, double *nnz_data, double *b)
Unpreconditioned solver.
Definition: precon.c:255
void lusgs_psolve(int bn, int *row_ptr, int *col_ind, int *diag_ind, double *nnz_data, double *b)
Solver function for LU-SGS preconditioner.
Definition: precon.c:187
#define blkdim
Definition: precon.c:30
ucfd_status_t lusgs_prepare(int bn, int *diag_ind, double *nnz_data)
LU-SGS preconditioner for BSR matrix format.
Definition: precon.c:167
void bilu_psolve(int bn, int *row_ptr, int *col_ind, int *diag_ind, double *nnz_data, double *b)
Solver function for BILU preconditioner.
Definition: precon.c:100
Header file for preconditioners for Krylov subspace methods.
ucfd_status_t
Definition: ucfd_types.h:10
@ UCFD_STATUS_SUCCESS
Definition: ucfd_types.h:12