From a41536c3986d075d89c21f0ebe1e509567c39ca7 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Fri, 26 Oct 2012 07:30:37 +0000 Subject: [PATCH] Merge to juropa --- AMDiS/src/parallel/PetscSolverNavierStokes.cc | 181 +++++++++++++----- AMDiS/src/parallel/PetscSolverNavierStokes.h | 4 + 2 files changed, 133 insertions(+), 52 deletions(-) diff --git a/AMDiS/src/parallel/PetscSolverNavierStokes.cc b/AMDiS/src/parallel/PetscSolverNavierStokes.cc index 6b2cf099..070c7f47 100644 --- a/AMDiS/src/parallel/PetscSolverNavierStokes.cc +++ b/AMDiS/src/parallel/PetscSolverNavierStokes.cc @@ -18,6 +18,51 @@ namespace AMDiS { using namespace std; + PetscErrorCode pcNs(PC pc, Vec x, Vec y) + { + void *ctx; + PCShellGetContext(pc, &ctx); + MatShellNavierStokesSchur* data = static_cast<MatShellNavierStokesSchur*>(ctx); + + Vec velocity, pressure; + VecGetSubVector(x, data->isVelocity, &velocity); + VecGetSubVector(x, data->isPressure, &pressure); + + Vec velocityTmp; + VecDuplicate(velocity, &velocityTmp); + + Vec pressureTmp; + VecDuplicate(pressure, &pressureTmp); + +#if 0 + MatMult(data->A01, pressure, velocityTmp); + VecAXPY(velocity, 1.0, velocityTmp); + KSPSolve(data->kspVelocity, velocity, velocity); + VecScale(pressure, -1.0); +#else + KSPSolve(data->kspVelocity, velocity, velocityTmp); + MatMult(data->A10, velocityTmp, pressureTmp); + VecAXPY(pressure, -1.0, pressureTmp); + + KSPSolve(data->kspLaplace, pressure, pressure); + MatMult(data->matConDif, pressure, pressureTmp); + KSPSolve(data->kspMass, pressureTmp, pressure); + + MatMult(data->A01, pressure, velocityTmp); + VecAXPY(velocity, -1.0, velocityTmp); + KSPSolve(data->kspVelocity, velocity, velocity); +#endif + + + VecRestoreSubVector(x, data->isVelocity, &velocity); + VecRestoreSubVector(x, data->isPressure, &pressure); + + VecCopy(x, y); + + VecDestroy(&velocityTmp); + VecDestroy(&pressureTmp); + } + int petscMultNavierStokesSchur(Mat mat, Vec x, Vec y) { void *ctx; @@ -47,9 +92,10 @@ namespace AMDiS { VecDuplicate(x, &vec0); VecDuplicate(x, &vec1); - KSPSolve(data->kspLaplace, x, vec0); - MatMult(data->matConDif, vec0, vec1); - KSPSolve(data->kspMass, vec1, y); + // KSPSolve(data->kspLaplace, x, vec0); + // MatMult(data->matConDif, vec0, vec1); + //KSPSolve(data->kspMass, vec0, y); + VecSet(y, 0.0); VecDestroy(&vec0); VecDestroy(&vec1); @@ -114,57 +160,31 @@ namespace AMDiS { { FUNCNAME("PetscSolverNavierStokes::initPreconditioner()"); - vector<int> velocityComponents; - velocityComponents.push_back(0); - velocityComponents.push_back(1); - - PCSetType(pc, PCFIELDSPLIT); - PCFieldSplitSetType(pc, PC_COMPOSITE_SCHUR); - PCFieldSplitSetSchurFactType(pc, PC_FIELDSPLIT_SCHUR_FACT_FULL); - createFieldSplit(pc, "velocity", velocityComponents); - createFieldSplit(pc, "pressure", pressureComponent); - - KSPSetUp(kspInterior); - - KSP *subKsp; - int nSubKsp; - PCFieldSplitGetSubKSP(pc, &nSubKsp, &subKsp); - - TEST_EXIT(nSubKsp == 2) - ("Wrong numer of KSPs inside of the fieldsplit preconditioner!\n"); - - KSP kspVelocity = subKsp[0]; - KSP kspSchur = subKsp[1]; - PetscFree(subKsp); - Mat A00, A01, A10, A11; - PCFieldSplitGetSchurBlocks(pc, &A00, &A01, &A10, &A11); - matShellContext.A00 = A00; - matShellContext.A01 = A01; - matShellContext.A10 = A10; - matShellContext.A11 = A11; - matShellContext.kspVelocity = kspVelocity; - - Mat matShell; - MatDuplicate(A11, MAT_DO_NOT_COPY_VALUES, &matShell); - MatSetType(matShell, MATSHELL); - MatShellSetContext(matShell, &matShellContext); - MatShellSetOperation(matShell, MATOP_MULT, (void(*)(void))petscMultNavierStokesSchur); - MatSetUp(matShell); - - KSPSetType(kspVelocity, KSPPREONLY); + PCSetType(pc, PCSHELL); + PCShellSetApply(pc, pcNs); + PCShellSetContext(pc, &matShellContext); + + interiorMap->createIndexSet(matShellContext.isVelocity, 0, 2); + interiorMap->createIndexSet(matShellContext.isPressure, 2, 1); + MatGetSubMatrix(getMatInterior(), matShellContext.isVelocity, + matShellContext.isVelocity, MAT_INITIAL_MATRIX, &matShellContext.A00); + MatGetSubMatrix(getMatInterior(), matShellContext.isVelocity, + matShellContext.isPressure, MAT_INITIAL_MATRIX, &matShellContext.A01); + MatGetSubMatrix(getMatInterior(), matShellContext.isPressure, + matShellContext.isVelocity, MAT_INITIAL_MATRIX, &matShellContext.A10); + MatGetSubMatrix(getMatInterior(), matShellContext.isPressure, + matShellContext.isPressure, MAT_INITIAL_MATRIX, &matShellContext.A11); + + KSPCreate(mpiCommGlobal, &(matShellContext.kspVelocity)); + KSPSetOperators(matShellContext.kspVelocity, matShellContext.A00, matShellContext.A00, SAME_NONZERO_PATTERN); + // KSPSetType(matShellContext.kspVelocity, KSPPREONLY); + KSPSetInitialGuessNonzero(matShellContext.kspVelocity, PETSC_TRUE); PC pcSub; - KSPGetPC(kspVelocity, &pcSub); + KSPGetPC(matShellContext.kspVelocity, &pcSub); PCSetType(pcSub, PCLU); PCFactorSetMatSolverPackage(pcSub, MATSOLVERMUMPS); - - - KSPSetType(kspSchur, KSPGMRES); - KSPSetTolerances(kspSchur, 0, 1e-14, 1e+3, 1000); - KSPSetOperators(kspSchur, matShell, matShell, SAME_NONZERO_PATTERN); - KSPGetPC(kspSchur, &pcSub); - PCSetType(pcSub, PCNONE); - + // === Mass matrix solver === @@ -217,9 +237,9 @@ namespace AMDiS { Simple_SOT conDif1(nu); conDifOp.addTerm(&conDif1); Vector_FOT conDif2(0); - // conDifOp.addTerm(&conDif2, GRD_PHI); + conDifOp.addTerm(&conDif2, GRD_PHI); Vector_FOT conDif3(1); - // conDifOp.addTerm(&conDif3, GRD_PHI); + conDifOp.addTerm(&conDif3, GRD_PHI); conDifMatrix.assembleOperator(conDifOp); @@ -232,6 +252,7 @@ namespace AMDiS { matShellContext.kspLaplace = laplaceMatrixSolver->getSolver(); matShellContext.matConDif = conDifMatrixSolver->getMatInterior(); + KSPSetType(matShellContext.kspMass, KSPRICHARDSON); KSPSetTolerances(matShellContext.kspMass, 0, 1e-13, 1e+3, 1); KSPGetPC(matShellContext.kspMass, &pcSub); @@ -240,16 +261,72 @@ namespace AMDiS { KSPSetFromOptions(matShellContext.kspMass); KSPSetType(matShellContext.kspLaplace, KSPCG); + KSPSetInitialGuessNonzero(matShellContext.kspLaplace, PETSC_TRUE); KSPSetTolerances(matShellContext.kspLaplace, 0, 1e-13, 1e+3, 10000); KSPGetPC(matShellContext.kspLaplace, &pcSub); PCSetType(pcSub, PCJACOBI); KSPSetFromOptions(matShellContext.kspLaplace); + + + +#if 0 + vector<int> velocityComponents; + velocityComponents.push_back(0); + velocityComponents.push_back(1); + + PCSetType(pc, PCFIELDSPLIT); + PCFieldSplitSetType(pc, PC_COMPOSITE_SCHUR); + PCFieldSplitSetSchurFactType(pc, PC_FIELDSPLIT_SCHUR_FACT_FULL); + createFieldSplit(pc, "velocity", velocityComponents); + createFieldSplit(pc, "pressure", pressureComponent); + + KSPSetUp(kspInterior); + + KSP *subKsp; + int nSubKsp; + PCFieldSplitGetSubKSP(pc, &nSubKsp, &subKsp); + + TEST_EXIT(nSubKsp == 2) + ("Wrong numer of KSPs inside of the fieldsplit preconditioner!\n"); + + KSP kspVelocity = subKsp[0]; + KSP kspSchur = subKsp[1]; + PetscFree(subKsp); + + Mat A00, A01, A10, A11; + PCFieldSplitGetSchurBlocks(pc, &A00, &A01, &A10, &A11); + matShellContext.A00 = A00; + matShellContext.A01 = A01; + matShellContext.A10 = A10; + matShellContext.A11 = A11; + matShellContext.kspVelocity = kspVelocity; + + Mat matShell; + MatDuplicate(A11, MAT_DO_NOT_COPY_VALUES, &matShell); + MatSetType(matShell, MATSHELL); + MatShellSetContext(matShell, &matShellContext); + MatShellSetOperation(matShell, MATOP_MULT, (void(*)(void))petscMultNavierStokesSchur); + + KSPSetType(kspVelocity, KSPPREONLY); + PC pcSub; + KSPGetPC(kspVelocity, &pcSub); + PCSetType(pcSub, PCLU); + PCFactorSetMatSolverPackage(pcSub, MATSOLVERMUMPS); + + + KSPSetType(kspSchur, KSPGMRES); + KSPSetTolerances(kspSchur, 0, 1e-14, 1e+3, 1000); + KSPSetOperators(kspSchur, matShell, matShell, SAME_NONZERO_PATTERN); + KSPGetPC(kspSchur, &pcSub); + PCSetType(pcSub, PCNONE); + matShellContext.solverMode = 1; KSPSetFromOptions(kspVelocity); KSPSetFromOptions(kspSchur); +#endif } } diff --git a/AMDiS/src/parallel/PetscSolverNavierStokes.h b/AMDiS/src/parallel/PetscSolverNavierStokes.h index 6f97c66c..302f2b70 100644 --- a/AMDiS/src/parallel/PetscSolverNavierStokes.h +++ b/AMDiS/src/parallel/PetscSolverNavierStokes.h @@ -44,6 +44,10 @@ namespace AMDiS { KSP kspMass, kspLaplace; Mat matConDif; + + + + IS isVelocity, isPressure; }; class PetscSolverNavierStokes : public PetscSolverGlobalMatrix -- GitLab