| fieldsplit.c (ab57588789c9da5248d756019688f1b680cba327) | fieldsplit.c (21635b76ed28834bc274bfdfd6051f93dfbfcb4f) |
|---|---|
| 1 2#include <petsc-private/pcimpl.h> /*I "petscpc.h" I*/ 3#include <petscdm.h> 4 5/* 6 There is a nice discussion of block preconditioners in 7 8[El08] A taxonomy and comparison of parallel block multi-level preconditioners for the incompressible Navier–Stokes equations --- 606 unchanged lines hidden (view full) --- 615 if (kspA != kspInner) { 616 ierr = KSPSetOperators(kspA,jac->mat[0],jac->pmat[0],pc->flag);CHKERRQ(ierr); 617 } 618 if (kspUpper != kspA) { 619 ierr = KSPSetOperators(kspUpper,jac->mat[0],jac->pmat[0],pc->flag);CHKERRQ(ierr); 620 } 621 ierr = KSPSetOperators(jac->kspschur,jac->schur,FieldSplitSchurPre(jac),pc->flag);CHKERRQ(ierr); 622 } else { | 1 2#include <petsc-private/pcimpl.h> /*I "petscpc.h" I*/ 3#include <petscdm.h> 4 5/* 6 There is a nice discussion of block preconditioners in 7 8[El08] A taxonomy and comparison of parallel block multi-level preconditioners for the incompressible Navier–Stokes equations --- 606 unchanged lines hidden (view full) --- 615 if (kspA != kspInner) { 616 ierr = KSPSetOperators(kspA,jac->mat[0],jac->pmat[0],pc->flag);CHKERRQ(ierr); 617 } 618 if (kspUpper != kspA) { 619 ierr = KSPSetOperators(kspUpper,jac->mat[0],jac->pmat[0],pc->flag);CHKERRQ(ierr); 620 } 621 ierr = KSPSetOperators(jac->kspschur,jac->schur,FieldSplitSchurPre(jac),pc->flag);CHKERRQ(ierr); 622 } else { |
| 623 KSP ksp; | |
| 624 const char *Dprefix; 625 char schurprefix[256]; 626 char schurtestoption[256]; 627 MatNullSpace sp; 628 PetscBool flg; 629 630 /* extract the A01 and A10 matrices */ 631 ilink = jac->head; 632 ierr = ISComplement(ilink->is_col,rstart,rend,&ccis);CHKERRQ(ierr); 633 ierr = MatGetSubMatrix(pc->mat,ilink->is,ccis,MAT_INITIAL_MATRIX,&jac->B);CHKERRQ(ierr); 634 ierr = ISDestroy(&ccis);CHKERRQ(ierr); 635 ilink = ilink->next; 636 ierr = ISComplement(ilink->is_col,rstart,rend,&ccis);CHKERRQ(ierr); 637 ierr = MatGetSubMatrix(pc->mat,ilink->is,ccis,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr); 638 ierr = ISDestroy(&ccis);CHKERRQ(ierr); 639 640 /* Use mat[0] (diagonal block of Amat) preconditioned by pmat[0] to define Schur complement */ 641 ierr = MatCreate(((PetscObject)jac->mat[0])->comm,&jac->schur);CHKERRQ(ierr); 642 ierr = MatSetType(jac->schur,MATSCHURCOMPLEMENT);CHKERRQ(ierr); | 623 const char *Dprefix; 624 char schurprefix[256]; 625 char schurtestoption[256]; 626 MatNullSpace sp; 627 PetscBool flg; 628 629 /* extract the A01 and A10 matrices */ 630 ilink = jac->head; 631 ierr = ISComplement(ilink->is_col,rstart,rend,&ccis);CHKERRQ(ierr); 632 ierr = MatGetSubMatrix(pc->mat,ilink->is,ccis,MAT_INITIAL_MATRIX,&jac->B);CHKERRQ(ierr); 633 ierr = ISDestroy(&ccis);CHKERRQ(ierr); 634 ilink = ilink->next; 635 ierr = ISComplement(ilink->is_col,rstart,rend,&ccis);CHKERRQ(ierr); 636 ierr = MatGetSubMatrix(pc->mat,ilink->is,ccis,MAT_INITIAL_MATRIX,&jac->C);CHKERRQ(ierr); 637 ierr = ISDestroy(&ccis);CHKERRQ(ierr); 638 639 /* Use mat[0] (diagonal block of Amat) preconditioned by pmat[0] to define Schur complement */ 640 ierr = MatCreate(((PetscObject)jac->mat[0])->comm,&jac->schur);CHKERRQ(ierr); 641 ierr = MatSetType(jac->schur,MATSCHURCOMPLEMENT);CHKERRQ(ierr); |
| 643 ierr = MatSchurComplementGetKSP(jac->schur, &ksp);CHKERRQ(ierr); 644 ierr = PetscSNPrintf(schurprefix, sizeof(schurprefix), "%sfieldsplit_%s_inner_", ((PetscObject)pc)->prefix ? ((PetscObject)pc)->prefix : "", ilink->splitname);CHKERRQ(ierr); 645 /* Indent this deeper to emphasize the "inner" nature of this solver. */ 646 ierr = PetscObjectIncrementTabLevel((PetscObject)ksp, (PetscObject) pc, 2);CHKERRQ(ierr); 647 ierr = KSPSetOptionsPrefix(ksp, schurprefix);CHKERRQ(ierr); | |
| 648 ierr = MatSchurComplementSet(jac->schur,jac->mat[0],jac->pmat[0],jac->B,jac->C,jac->mat[1]);CHKERRQ(ierr); 649 650 ierr = MatGetNullSpace(jac->pmat[1], &sp);CHKERRQ(ierr); 651 if (sp) { 652 ierr = MatSetNullSpace(jac->schur, sp);CHKERRQ(ierr); 653 } 654 655 ierr = PetscSNPrintf(schurtestoption, sizeof(schurtestoption), "-fieldsplit_%s_inner_", ilink->splitname);CHKERRQ(ierr); 656 ierr = PetscOptionsFindPairPrefix_Private(((PetscObject)pc)->prefix, schurtestoption, NULL, &flg);CHKERRQ(ierr); 657 if (flg) { | 642 ierr = MatSchurComplementSet(jac->schur,jac->mat[0],jac->pmat[0],jac->B,jac->C,jac->mat[1]);CHKERRQ(ierr); 643 644 ierr = MatGetNullSpace(jac->pmat[1], &sp);CHKERRQ(ierr); 645 if (sp) { 646 ierr = MatSetNullSpace(jac->schur, sp);CHKERRQ(ierr); 647 } 648 649 ierr = PetscSNPrintf(schurtestoption, sizeof(schurtestoption), "-fieldsplit_%s_inner_", ilink->splitname);CHKERRQ(ierr); 650 ierr = PetscOptionsFindPairPrefix_Private(((PetscObject)pc)->prefix, schurtestoption, NULL, &flg);CHKERRQ(ierr); 651 if (flg) { |
| 658 DM dmInner; | 652 DM dmInner; 653 KSP kspInner; |
| 659 | 654 |
| 655 ierr = MatSchurComplementGetKSP(jac->schur, &kspInner);CHKERRQ(ierr); 656 ierr = PetscSNPrintf(schurprefix, sizeof(schurprefix), "%sfieldsplit_%s_inner_", ((PetscObject)pc)->prefix ? ((PetscObject)pc)->prefix : "", ilink->splitname);CHKERRQ(ierr); 657 /* Indent this deeper to emphasize the "inner" nature of this solver. */ 658 ierr = PetscObjectIncrementTabLevel((PetscObject)kspInner, (PetscObject) pc, 2);CHKERRQ(ierr); 659 ierr = KSPSetOptionsPrefix(kspInner, schurprefix);CHKERRQ(ierr); 660 |
|
| 660 /* Set DM for new solver */ 661 ierr = KSPGetDM(jac->head->ksp, &dmInner);CHKERRQ(ierr); | 661 /* Set DM for new solver */ 662 ierr = KSPGetDM(jac->head->ksp, &dmInner);CHKERRQ(ierr); |
| 662 ierr = KSPSetDM(ksp, dmInner);CHKERRQ(ierr); 663 ierr = KSPSetDMActive(ksp, PETSC_FALSE);CHKERRQ(ierr); 664 ierr = KSPSetOperators(jac->head->ksp,jac->mat[0],jac->pmat[0],flag);CHKERRQ(ierr); 665 ierr = KSPSetFromOptions(jac->head->ksp);CHKERRQ(ierr); | 663 ierr = KSPSetDM(kspInner, dmInner);CHKERRQ(ierr); 664 ierr = KSPSetDMActive(kspInner, PETSC_FALSE);CHKERRQ(ierr); |
| 666 } else { | 665 } else { |
| 667 ierr = MatSchurComplementSetKSP(jac->schur, jac->head->ksp);CHKERRQ(ierr); | 666 /* Use the outer solver for the inner solve, but revert the KSPPREONLY from PCFieldSplitSetFields_FieldSplit or 667 * PCFieldSplitSetIS_FieldSplit. We don't want KSPPREONLY because it makes the Schur complement inexact, 668 * preventing Schur complement reduction to be an accurate solve. Usually when an iterative solver is used for 669 * S = D - C A_inner^{-1} B, we expect S to be defined using an accurate definition of A_inner^{-1}, so we make 670 * GMRES the default. Note that it is also common to use PREONLY for S, in which case S may not be used 671 * directly, and the user is responsible for setting an inexact method for fieldsplit's A^{-1}. */ 672 ierr = KSPSetType(jac->head->ksp,KSPGMRES);CHKERRQ(ierr); 673 ierr = MatSchurComplementSetKSP(jac->schur,jac->head->ksp);CHKERRQ(ierr); |
| 668 } | 674 } |
| 675 ierr = KSPSetOperators(jac->head->ksp,jac->mat[0],jac->pmat[0],flag);CHKERRQ(ierr); 676 ierr = KSPSetFromOptions(jac->head->ksp);CHKERRQ(ierr); |
|
| 669 ierr = MatSetFromOptions(jac->schur);CHKERRQ(ierr); 670 671 ierr = PetscSNPrintf(schurtestoption, sizeof(schurtestoption), "-fieldsplit_%s_upper_", ilink->splitname);CHKERRQ(ierr); 672 ierr = PetscOptionsFindPairPrefix_Private(((PetscObject)pc)->prefix, schurtestoption, NULL, &flg);CHKERRQ(ierr); 673 if (flg) { 674 DM dmInner; 675 676 ierr = PetscSNPrintf(schurprefix, sizeof(schurprefix), "%sfieldsplit_%s_upper_", ((PetscObject)pc)->prefix ? ((PetscObject)pc)->prefix : "", ilink->splitname);CHKERRQ(ierr); --- 1186 unchanged lines hidden --- | 677 ierr = MatSetFromOptions(jac->schur);CHKERRQ(ierr); 678 679 ierr = PetscSNPrintf(schurtestoption, sizeof(schurtestoption), "-fieldsplit_%s_upper_", ilink->splitname);CHKERRQ(ierr); 680 ierr = PetscOptionsFindPairPrefix_Private(((PetscObject)pc)->prefix, schurtestoption, NULL, &flg);CHKERRQ(ierr); 681 if (flg) { 682 DM dmInner; 683 684 ierr = PetscSNPrintf(schurprefix, sizeof(schurprefix), "%sfieldsplit_%s_upper_", ((PetscObject)pc)->prefix ? ((PetscObject)pc)->prefix : "", ilink->splitname);CHKERRQ(ierr); --- 1186 unchanged lines hidden --- |