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) {
47 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
53 static void decouple_anl(dBSRmat* A, REAL* diaginv, dBSRmat* B)
56 const INT ROW = A->ROW;
57 const INT NNZ = A->NNZ;
59 const INT nb2 = nb * nb;
60 const INT* IA = A->IA;
61 const INT* JA = A->JA;
70 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
71 memcpy(JAb, JA, NNZ *
sizeof(INT));
73 for (i = 0; i < ROW; ++i) {
75 for (k = IA[i]; k < IA[i + 1]; ++k) {
78 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
79 for (
int l = 0; l < nb - 1; l++)
80 diaginv[i * nb2 + 1 + l] = -val[m + 1 + l];
85 for (k = IA[i]; k < IA[i + 1]; ++k) {
87 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
92 static void decouple_truetrans(dBSRmat* A, REAL* diaginv, dBSRmat* B)
95 const INT ROW = A->ROW;
96 const INT NNZ = A->NNZ;
98 const INT nb2 = nb * nb;
99 const INT* IA = A->IA;
100 const INT* JA = A->JA;
109 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
110 memcpy(JAb, JA, NNZ *
sizeof(INT));
113 mat1 =
new REAL[nb2];
114 mat2 =
new REAL[nb2];
117 for (i = 0; i < ROW; ++i) {
121 fasp_smat_identity(mat2, nb, nb2);
123 fasp_smat_identity(mat1, nb, nb2);
125 for (l = 1; l < nb; ++l) {
126 mat2[l] = diaginv[i * nb2 + l];
127 Tt += diaginv[i * nb2 + l] * diaginv[i * nb2 + l * nb];
129 for (k = IA[i]; k < IA[i + 1]; ++k) {
130 if (JA[k] == i)
break;
132 for (l = 0; l < nb - 1; ++l) {
133 if (val[k * nb2 + (l + 1) * nb] > 0)
134 mat1[(l + 1) * nb] = -diaginv[i * nb2 + (l + 1) * nb] / Tt;
136 DaABpbC(nb, nb, nb, 1, mat1, mat2, 0, diaginv + i * nb2);
139 for (k = IA[i]; k < IA[i + 1]; ++k) {
141 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
149 static void decouple_truetrans_alg(dBSRmat* A, REAL* diaginv, dBSRmat* B)
152 const INT ROW = A->ROW;
153 const INT NNZ = A->NNZ;
154 const INT nb = A->nb;
155 const INT nb2 = nb * nb;
156 const INT* IA = A->IA;
157 const INT* JA = A->JA;
166 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
167 memcpy(JAb, JA, NNZ *
sizeof(INT));
170 mat1 =
new REAL[nb2];
171 mat2 =
new REAL[nb2];
174 for (i = 0; i < ROW; ++i) {
175 for (k = IA[i]; k < IA[i + 1]; ++k) {
179 fasp_smat_identity(mat2, nb, nb2);
180 for (l = 1; l < nb; ++l) {
181 mat2[l] = -val[m + l];
182 if (val[m + l * nb] > 0) {
183 Tt += -val[m + l] * val[m + l * nb];
187 fasp_smat_identity(mat1, nb, nb2);
188 for (l = 1; l < nb; ++l) {
189 if (val[m + l * nb] > 0) {
190 mat1[l * nb] = -val[m + l * nb] / Tt;
194 DaABpbC(nb, nb, nb, 1, mat1, mat2, 0, diaginv + i * nb2);
199 for (k = IA[i]; k < IA[i + 1]; ++k) {
201 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
210 static void decouple_abftrue(dBSRmat* A, REAL* diaginv, dBSRmat* B)
213 const INT ROW = A->ROW;
214 const INT NNZ = A->NNZ;
215 const INT nb = A->nb;
216 const INT nb2 = nb * nb;
217 const INT* IA = A->IA;
218 const INT* JA = A->JA;
227 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
228 memcpy(JAb, JA, NNZ *
sizeof(INT));
230 for (i = 0; i < ROW; ++i) {
232 for (k = IA[i]; k < IA[i + 1]; ++k) {
235 memcpy(diaginv + i * nb2, val + k * nb2, nb2 *
sizeof(REAL));
236 fasp_smat_inv(diaginv + i * nb2, nb);
239 diaginv[i * nb2] = 1;
240 for (
int l = 0; l < nb - 1; l++)
241 diaginv[i * nb2 + 1 + l] = -val[m + 1 + l];
246 for (k = IA[i]; k < IA[i + 1]; ++k) {
248 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
253 static void decouple_true_scale(dBSRmat* A, REAL* diaginv, dBSRmat* B)
256 const INT ROW = A->ROW;
257 const INT NNZ = A->NNZ;
258 const INT nb = A->nb;
259 const INT nb2 = nb * nb;
260 const INT* IA = A->IA;
261 const INT* JA = A->JA;
270 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
271 memcpy(JAb, JA, NNZ *
sizeof(INT));
273 for (i = 0; i < ROW; ++i) {
275 for (k = IA[i]; k < IA[i + 1]; ++k) {
278 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
279 diaginv[i * nb2] = 1 / val[m];
280 for (
int l = 0; l < nb - 1; l++)
281 diaginv[i * nb2 + 1 + l] = -val[m + 1 + l] / val[m];
286 for (k = IA[i]; k < IA[i + 1]; ++k) {
288 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
293 static void decouple_rotate(dBSRmat* A, REAL* diaginv, dBSRmat* B)
296 const INT ROW = A->ROW;
297 const INT NNZ = A->NNZ;
298 const INT nb = A->nb;
299 const INT nb2 = nb * nb;
300 const INT* IA = A->IA;
301 const INT* JA = A->JA;
310 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
311 memcpy(JAb, JA, NNZ *
sizeof(INT));
313 for (i = 0; i < ROW; ++i) {
315 for (k = IA[i]; k < IA[i + 1]; ++k) {
318 for (
int li = 0; li < nb; li++) {
319 for (
int lj = 0; lj < nb; lj++) {
320 diaginv[i * nb2 + li * nb + lj] = 0;
322 diaginv[i * nb2 + li * nb + lj] = 1;
324 if (lj == 0 && li == nb - 1) {
325 diaginv[i * nb2 + li * nb + lj] = 1;
333 for (k = IA[i]; k < IA[i + 1]; ++k) {
335 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
341 static void decouple_quasi(dBSRmat* A, REAL* diaginv, dBSRmat* B)
344 const INT ROW = A->ROW;
345 const INT NNZ = A->NNZ;
346 const INT nb = A->nb;
347 const INT nb2 = nb * nb;
348 const INT* IA = A->IA;
349 const INT* JA = A->JA;
357 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
358 memcpy(JAb, JA, NNZ *
sizeof(INT));
360 for (i = 0; i < ROW; ++i) {
362 for (k = IA[i]; k < IA[i + 1]; ++k) {
365 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
366 for (
int l = 0; l < nb - 1; l++)
367 diaginv[i * nb2 + 1 + l] =
368 -val[m + 1 + l] / val[m + (l + 1) * nb + l + 1];
373 for (k = IA[i]; k < IA[i + 1]; ++k) {
375 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
381 static void decouple_trueabf(dBSRmat* A, REAL* diaginv, dBSRmat* B)
384 const INT ROW = A->ROW;
385 const INT NNZ = A->NNZ;
386 const INT nb = A->nb;
387 const INT nb2 = nb * nb;
388 const INT* IA = A->IA;
389 const INT* JA = A->JA;
397 memcpy(IAb, IA, (ROW + 1) *
sizeof(INT));
398 memcpy(JAb, JA, NNZ *
sizeof(INT));
400 for (i = 0; i < ROW; ++i) {
402 for (k = IA[i]; k < IA[i + 1]; ++k) {
405 fasp_smat_identity(diaginv + i * nb2, nb, nb2);
406 for (
int l = 0; l < nb; l++) diaginv[i * nb2 + l] = val[m + l];
407 fasp_smat_inv(diaginv + i * nb2, nb);
412 for (k = IA[i]; k < IA[i + 1]; ++k) {
414 fasp_blas_smat_mul(diaginv + i * nb2, val + m, valb + m, nb);
420 void VectorFaspSolver::Decoupling(dBSRmat* Absr,
428 int nrow = Absr->ROW;
430 double* Dmat = Dmatvec;
431 precond_diag_bsr diagA;
434 for (
int i = 0; i < nrow; ++i) order->val[i] = i;
437 if (decoupleType == 0) {
438 fasp_dbsr_cp(Absr, Asc);
439 fasp_dvec_cp(b, fsc);
444 switch (decoupleType) {
446 decouple_anl(Absr, Dmat, Asc);
449 decouple_quasi(Absr, Dmat, Asc);
452 decouple_trueabf(Absr, Dmat, Asc);
455 decouple_abftrue(Absr, Dmat, Asc);
458 decouple_abftrue(Absr, Dmat, Asc);
461 decouple_truetrans_alg(Absr, Dmat, Asc);
464 decouple_truetrans(Absr, Dmat, Asc);
467 decouple_true_scale(Absr, Dmat, Asc);
470 decouple_rotate(Absr, Dmat, Asc);
473 decouple_abf(Absr, Dmat, Asc);
476 diagA.diag.row = nrow * nb * nb;
477 diagA.diag.val = Dmat;
479 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.