16 static void decouple_abf(dBSRmat* A, REAL* diaginv, dBSRmat* B)
19 const INT ROW = A->ROW;
20 const INT NNZ = A->NNZ;
22 const INT nb2 = nb * nb;
23 const INT* IA = A->IA;
24 const INT* JA = A->JA;
33 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
34 memcpy(JAb, JA, NNZ *
sizeof(INT));
36 for (i = 0; i < ROW; ++i) {
38 for (k = IA[i]; k < IA[i + 1]; ++k) {
40 memcpy(diaginv + i * nb2, val + k * nb2, nb2 *
sizeof(REAL));
41 fasp_smat_inv(diaginv + i * nb2, nb);
45 for (k = IA[i]; k < IA[i + 1]; ++k) {
48 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
54 static void decouple_anl(dBSRmat* A, REAL* diaginv, dBSRmat* B)
57 const INT ROW = A->ROW;
58 const INT NNZ = A->NNZ;
60 const INT nb2 = nb * nb;
61 const INT* IA = A->IA;
62 const INT* JA = A->JA;
71 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
72 memcpy(JAb, JA, NNZ *
sizeof(INT));
74 for (i = 0; i < ROW; ++i) {
76 for (k = IA[i]; k < IA[i + 1]; ++k) {
79 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
80 for (
int l = 0; l < nb - 1; l++)
81 diaginv[i * nb2 + 1 + l] = -val[m + 1 + l];
86 for (k = IA[i]; k < IA[i + 1]; ++k) {
89 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
94 static void decouple_truetrans(dBSRmat* A, REAL* diaginv, dBSRmat* B)
97 const INT ROW = A->ROW;
98 const INT NNZ = A->NNZ;
100 const INT nb2 = nb * nb;
101 const INT* IA = A->IA;
102 const INT* JA = A->JA;
111 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
112 memcpy(JAb, JA, NNZ *
sizeof(INT));
115 mat1 =
new REAL[nb2];
116 mat2 =
new REAL[nb2];
119 for (i = 0; i < ROW; ++i) {
123 fasp_smat_identity(mat2, nb, nb2);
125 fasp_smat_identity(mat1, nb, nb2);
127 for (l = 1; l < nb; ++l) {
128 mat2[l] = diaginv[i * nb2 + l];
129 Tt += diaginv[i * nb2 + l] * diaginv[i * nb2 + l * nb];
131 for (k = IA[i]; k < IA[i + 1]; ++k) {
132 if (JA[k] == i)
break;
134 for (l = 0; l < nb - 1; ++l) {
135 if (val[k * nb2 + (l + 1) * nb] > 0)
136 mat1[(l + 1) * nb] = -diaginv[i * nb2 + (l + 1) * nb] / Tt;
138 DaABpbC(nb, nb, nb, 1, mat1, mat2, 0, diaginv + i * nb2);
141 for (k = IA[i]; k < IA[i + 1]; ++k) {
144 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
152 static void decouple_truetrans_alg(dBSRmat* A, REAL* diaginv, dBSRmat* B)
155 const INT ROW = A->ROW;
156 const INT NNZ = A->NNZ;
157 const INT nb = A->nb;
158 const INT nb2 = nb * nb;
159 const INT* IA = A->IA;
160 const INT* JA = A->JA;
169 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
170 memcpy(JAb, JA, NNZ *
sizeof(INT));
173 mat1 =
new REAL[nb2];
174 mat2 =
new REAL[nb2];
177 for (i = 0; i < ROW; ++i) {
178 for (k = IA[i]; k < IA[i + 1]; ++k) {
182 fasp_smat_identity(mat2, nb, nb2);
183 for (l = 1; l < nb; ++l) {
184 mat2[l] = -val[m + l];
185 if (val[m + l * nb] > 0) {
186 Tt += -val[m + l] * val[m + l * nb];
190 fasp_smat_identity(mat1, nb, nb2);
191 for (l = 1; l < nb; ++l) {
192 if (val[m + l * nb] > 0) {
193 mat1[l * nb] = -val[m + l * nb] / Tt;
197 DaABpbC(nb, nb, nb, 1, mat1, mat2, 0, diaginv + i * nb2);
202 for (k = IA[i]; k < IA[i + 1]; ++k) {
205 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
214 static void decouple_abftrue(dBSRmat* A, REAL* diaginv, dBSRmat* B)
217 const INT ROW = A->ROW;
218 const INT NNZ = A->NNZ;
219 const INT nb = A->nb;
220 const INT nb2 = nb * nb;
221 const INT* IA = A->IA;
222 const INT* JA = A->JA;
231 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
232 memcpy(JAb, JA, NNZ *
sizeof(INT));
234 for (i = 0; i < ROW; ++i) {
236 for (k = IA[i]; k < IA[i + 1]; ++k) {
239 memcpy(diaginv + i * nb2, val + k * nb2, nb2 *
sizeof(REAL));
240 fasp_smat_inv(diaginv + i * nb2, nb);
243 diaginv[i * nb2] = 1;
244 for (
int l = 0; l < nb - 1; l++)
245 diaginv[i * nb2 + 1 + l] = -val[m + 1 + l];
250 for (k = IA[i]; k < IA[i + 1]; ++k) {
253 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
258 static void decouple_true_scale(dBSRmat* A, REAL* diaginv, dBSRmat* B)
261 const INT ROW = A->ROW;
262 const INT NNZ = A->NNZ;
263 const INT nb = A->nb;
264 const INT nb2 = nb * nb;
265 const INT* IA = A->IA;
266 const INT* JA = A->JA;
275 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
276 memcpy(JAb, JA, NNZ *
sizeof(INT));
278 for (i = 0; i < ROW; ++i) {
280 for (k = IA[i]; k < IA[i + 1]; ++k) {
283 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
284 diaginv[i * nb2] = 1 / val[m];
285 for (
int l = 0; l < nb - 1; l++)
286 diaginv[i * nb2 + 1 + l] = -val[m + 1 + l] / val[m];
291 for (k = IA[i]; k < IA[i + 1]; ++k) {
294 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
299 static void decouple_rotate(dBSRmat* A, REAL* diaginv, dBSRmat* B)
302 const INT ROW = A->ROW;
303 const INT NNZ = A->NNZ;
304 const INT nb = A->nb;
305 const INT nb2 = nb * nb;
306 const INT* IA = A->IA;
307 const INT* JA = A->JA;
316 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
317 memcpy(JAb, JA, NNZ *
sizeof(INT));
319 for (i = 0; i < ROW; ++i) {
321 for (k = IA[i]; k < IA[i + 1]; ++k) {
324 for (
int li = 0; li < nb; li++) {
325 for (
int lj = 0; lj < nb; lj++) {
326 diaginv[i * nb2 + li * nb + lj] = 0;
328 diaginv[i * nb2 + li * nb + lj] = 1;
330 if (lj == 0 && li == nb - 1) {
331 diaginv[i * nb2 + li * nb + lj] = 1;
339 for (k = IA[i]; k < IA[i + 1]; ++k) {
342 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
348 static void decouple_quasi(dBSRmat* A, REAL* diaginv, dBSRmat* B)
351 const INT ROW = A->ROW;
352 const INT NNZ = A->NNZ;
353 const INT nb = A->nb;
354 const INT nb2 = nb * nb;
355 const INT* IA = A->IA;
356 const INT* JA = A->JA;
364 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
365 memcpy(JAb, JA, NNZ *
sizeof(INT));
367 for (i = 0; i < ROW; ++i) {
369 for (k = IA[i]; k < IA[i + 1]; ++k) {
372 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
373 for (
int l = 0; l < nb - 1; l++)
374 diaginv[i * nb2 + 1 + l] =
375 -val[m + 1 + l] / val[m + (l + 1) * nb + l + 1];
380 for (k = IA[i]; k < IA[i + 1]; ++k) {
383 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
389 static void decouple_trueabf(dBSRmat* A, REAL* diaginv, dBSRmat* B)
392 const INT ROW = A->ROW;
393 const INT NNZ = A->NNZ;
394 const INT nb = A->nb;
395 const INT nb2 = nb * nb;
396 const INT* IA = A->IA;
397 const INT* JA = A->JA;
405 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
406 memcpy(JAb, JA, NNZ *
sizeof(INT));
408 for (i = 0; i < ROW; ++i) {
410 for (k = IA[i]; k < IA[i + 1]; ++k) {
413 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
414 for (
int l = 0; l < nb; l++) diaginv[i * nb2 + l] = val[m + l];
415 fasp_smat_inv(diaginv + i * nb2, nb);
420 for (k = IA[i]; k < IA[i + 1]; ++k) {
423 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
428 static void decouple_rowsum(dBSRmat* A, REAL* diaginv, dBSRmat* B)
431 const INT ROW = A->ROW;
432 const INT NNZ = A->NNZ;
433 const INT nb = A->nb;
434 const INT nb2 = nb * nb;
435 const INT* IA = A->IA;
436 const INT* JA = A->JA;
445 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
446 memcpy(JAb, JA, NNZ *
sizeof(INT));
448 for (i = 0; i < ROW; ++i) {
450 for (k = IA[i]; k < IA[i + 1]; ++k) {
453 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
454 for (
int l = 0; l < nb - 1; l++) diaginv[i * nb2 + 1 + l] = 1;
459 for (k = IA[i]; k < IA[i + 1]; ++k) {
462 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
468 void VectorFaspSolver::Decoupling(dBSRmat* Absr, dvector* b, dBSRmat* Asc, dvector* fsc,
469 ivector* order,
double* Dmatvec,
int decoupleType)
471 int nrow = Absr->ROW;
473 double* Dmat = Dmatvec;
474 precond_diag_bsr diagA;
477 for (
int i = 0; i < nrow; ++i) order->val[i] = i;
480 if (decoupleType == 0) {
481 fasp_dbsr_cp(Absr, Asc);
482 fasp_dvec_cp(b, fsc);
487 switch (decoupleType) {
489 decouple_anl(Absr, Dmat, Asc);
492 decouple_quasi(Absr, Dmat, Asc);
495 decouple_trueabf(Absr, Dmat, Asc);
498 decouple_abftrue(Absr, Dmat, Asc);
501 decouple_abftrue(Absr, Dmat, Asc);
504 decouple_truetrans_alg(Absr, Dmat, Asc);
507 decouple_truetrans(Absr, Dmat, Asc);
510 decouple_true_scale(Absr, Dmat, Asc);
513 decouple_rotate(Absr, Dmat, Asc);
516 decouple_abf(Absr, Dmat, Asc);
519 diagA.diag.row = nrow * nb * nb;
520 diagA.diag.val = Dmat;
522 fasp_precond_dbsr_diag(b->val, fsc->val, &diagA);
Operations about small dense mat.
void DaABpbC(const int &m, const int &n, const int &k, const double &alpha, const double *A, const double *B, const double &beta, double *C)
Computes C' = alpha B'A' + beta C', all matrices are column-major.
Declaration of classes interfacing to the FASP solvers.