UCFD_SPARSE  v1.0
Documentation
Loading...
Searching...
No Matches
precon.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <math.h>
4#include "mkl.h"
5#include "precon.h"
6
7
8// !! Diagonal matrices are inverted !!
9// !! CANNOT be applied into MKL sparse trsv function !!
10ucfd_precon_status_t ilu0_prepare_bsr(const int neles, const int nvars, \
11 const int *row_ptr, const int *col_ind, const int *diag_ind, double *nnz_data)
12{
13 int idx, jdx, kdx, ldx, mdx, row, col;
14 int st, ed, ijdx, kjdx, ijed, kjed;
15 double mat[nvars*nvars];
16 int ijarr[nvars+3], kjarr[nvars+3];
17 lapack_int info, *ipiv;
18
19 // Allocate memory
20 ipiv = (lapack_int *)malloc(sizeof(lapack_int)*nvars);
21
22 for (idx=0; idx<neles; idx++) {
23 st = row_ptr[idx];
24 ed = diag_ind[idx];
25
26 for (kdx=st; kdx<ed; kdx++) {
27 ldx = diag_ind[col_ind[kdx]];
28 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nvars, nvars, nvars, 1.0, \
29 &nnz_data[kdx*nvars*nvars], nvars, &nnz_data[ldx*nvars*nvars], nvars, 0.0, mat, nvars);
30 cblas_dcopy(nvars*nvars, mat, 1, &nnz_data[kdx*nvars*nvars], 1);
31
32 ijdx = kdx + 1;
33 kjdx = ldx + 1;
34 ijed = row_ptr[idx+1];
35 kjed = row_ptr[col_ind[kdx] + 1];
36 mdx = 0;
37 while (kjdx < kjed && ijdx < ijed) {
38 if (col_ind[ijdx] == col_ind[kjdx]) {
39 ijarr[mdx] = ijdx;
40 kjarr[mdx] = kjdx;
41 mdx++;
42 kjdx++;
43 ijdx++;
44 }
45 else if (col_ind[ijdx] < col_ind[kjdx]) ijdx++;
46 else kjdx++;
47 }
48
49 // A[i,j] = A[i,j] - A[i,k] @ A[k,j]
50 for (jdx=0; jdx<mdx; jdx++) {
51 ijdx = ijarr[jdx];
52 kjdx = kjarr[jdx];
53 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nvars, nvars, nvars, -1.0, \
54 mat, nvars, &nnz_data[kjdx*nvars*nvars], nvars, 1.0, &nnz_data[ijdx*nvars*nvars], nvars);
55 }
56 }
57 info = LAPACKE_dgetrf(LAPACK_ROW_MAJOR, nvars, nvars, &nnz_data[ed*nvars*nvars], nvars, ipiv);
58 if (info != 0) printf("Lapack dgetrf function error\n");
59 info = LAPACKE_dgetri(LAPACK_ROW_MAJOR, nvars, &nnz_data[ed*nvars*nvars], nvars, ipiv);
60 if (info != 0) printf("Lapack dgetrf function error\n");
61 }
62
63 free(ipiv);
64
66}
67
68
69// * MKL sparse function ver.
70ucfd_precon_status_t ilu0_sweep_bsr_mkl(sparse_matrix_t op, double *b)
71{
72 sparse_status_t status;
73 struct matrix_descr ldescr, udescr;
74
75 // Set matrix_description values
76 // Lower-triangular matrix
77 ldescr.type = SPARSE_MATRIX_TYPE_BLOCK_TRIANGULAR;
78 ldescr.mode = SPARSE_FILL_MODE_LOWER;
79 ldescr.diag = SPARSE_DIAG_UNIT;
80
81 // Upper-triangular matrix
82 udescr.type = SPARSE_MATRIX_TYPE_BLOCK_TRIANGULAR;
83 udescr.mode = SPARSE_FILL_MODE_UPPER;
84 udescr.diag = SPARSE_DIAG_NON_UNIT;
85
86 status = mkl_sparse_d_trsv(SPARSE_OPERATION_NON_TRANSPOSE, 1.0, op, ldescr, b, b);
87 if (status != SPARSE_STATUS_SUCCESS) return UCFD_PRECON_SPARSE_FAILED;
88 status = mkl_sparse_d_trsv(SPARSE_OPERATION_NON_TRANSPOSE, 1.0, op, udescr, b, b);
89 if (status != SPARSE_STATUS_SUCCESS) return UCFD_PRECON_SPARSE_FAILED;
90
92}
93
94
95// * Pure C function ver.
96ucfd_precon_status_t ilu0_sweep_bsr(const int neles, const int nvars, const int *row_ptr, const int *col_ind, const int *diag_ind, \
97 double *nnz_data, double *b)
98{
99 int idx, jdx, kdx, row, col;
100 int dd, st, ed, cind;
101 double arr[nvars];
102
103 // Solve Lower-triangular matrix
104 for (idx=0; idx<neles; idx++) {
105 cblas_dcopy(nvars, &b[idx*nvars], 1, arr, 1);
106
107 dd = diag_ind[idx];
108 st = row_ptr[idx];
109
110 for (jdx=st; jdx<dd; jdx++) {
111 cind = col_ind[jdx];
112
113 cblas_dgemv(CblasRowMajor, CblasNoTrans, nvars, nvars, -1.0, &nnz_data[jdx*nvars*nvars], nvars, \
114 &b[cind*nvars], 1, 1.0, arr, 1);
115 }
116
117 cblas_dcopy(nvars, arr, 1, &b[idx*nvars], 1);
118 }
119
120 // Solve Upper-triangular matrix
121 for (idx=neles-1; idx>-1; idx--) {
122 cblas_dcopy(nvars, &b[idx*nvars], 1, arr, 1);
123
124 dd = diag_ind[idx];
125 ed = row_ptr[idx+1];
126
127 for (jdx=(dd+1); jdx<ed; jdx++) {
128 cind = col_ind[jdx];
129
130 cblas_dgemv(CblasRowMajor, CblasNoTrans, nvars, nvars, -1.0, &nnz_data[jdx*nvars*nvars], nvars, \
131 &b[cind*nvars], 1, 1.0, arr, 1);
132 }
133
134 cblas_dgemv(CblasRowMajor, CblasNoTrans, nvars, nvars, 1.0, &nnz_data[dd*nvars*nvars], nvars, \
135 arr, 1, 1.0, &b[idx*nvars], 1);
136 }
137
138 return UCFD_PRECON_SUCCESS;
139}
140
141
142
143
#define nvars
Definition: mpi3d.c:31
ucfd_precon_status_t ilu0_prepare_bsr(const int neles, const int nvars, const int *row_ptr, const int *col_ind, const int *diag_ind, double *nnz_data)
Definition: precon.c:10
ucfd_precon_status_t ilu0_sweep_bsr_mkl(sparse_matrix_t op, double *b)
Definition: precon.c:70
ucfd_precon_status_t ilu0_sweep_bsr(const int neles, const int nvars, const int *row_ptr, const int *col_ind, const int *diag_ind, double *nnz_data, double *b)
Definition: precon.c:96
ucfd_precon_status_t
Definition: types.h:21
@ UCFD_PRECON_SPARSE_FAILED
Definition: types.h:22
@ UCFD_PRECON_SUCCESS
Definition: types.h:23