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.