diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h index 59bd92234e30807c46fa55bc0e963d1375998b8d..7c831b20e1fd050d702ed3bd62700f61ad8cf6d0 100644 --- a/AMDiS/src/AMDiS.h +++ b/AMDiS/src/AMDiS.h @@ -145,6 +145,8 @@ #include "parallel/Mtl4Solver.h" #else #include "parallel/PetscProblemStat.h" +#include "parallel/PetscSolver.h" +#include "parallel/PetscSolverNavierStokes.h" #endif #endif diff --git a/AMDiS/src/AMDiS_fwd.h b/AMDiS/src/AMDiS_fwd.h index a3ecfb0e8dcd4b7118aeecd7f15284b531a503e0..09f1ac32e38f4eeb5b0d9f192d4d36ab97ea7190 100644 --- a/AMDiS/src/AMDiS_fwd.h +++ b/AMDiS/src/AMDiS_fwd.h @@ -103,6 +103,7 @@ namespace AMDiS { class FeSpaceDofMap; class MatrixNnzStructure; class MeshLevelData; + class PetscSolver; class PetscSolverFeti; class PetscSolverFetiDebug; #endif diff --git a/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc b/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc index 3fbc4cc0d7635a264cefd8638663c11ca7435cc0..6728b3bb73b1bc70403c9b7b3a6894a3954a43f1 100644 --- a/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc +++ b/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc @@ -10,8 +10,8 @@ // See also license.opensource.txt in the distribution. -#include "AMDiS.h" #include "parallel/ParallelCoarseSpaceMatVec.h" +#include "parallel/ParallelDofMapping.h" #include "parallel/MatrixNnzStructure.h" namespace AMDiS { diff --git a/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.h b/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.h index b4911552195c7006dd666d0ac533f59a66baa196..e1bcd2ce2ef4ad7f427063ae833d89478f9af9bb 100644 --- a/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.h +++ b/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.h @@ -23,10 +23,13 @@ #ifndef AMDIS_PARALLEL_COARSE_SPACE_MAT_VEC_H #define AMDIS_PARALLEL_COARSE_SPACE_MAT_VEC_H +#include <mpi.h> #include <vector> #include <map> #include <petsc.h> #include "AMDiS_fwd.h" +#include "parallel/ParallelDofMapping.h" +#include "parallel/MeshDistributor.h" #include "parallel/MatrixNnzStructure.h" namespace AMDiS { diff --git a/AMDiS/src/parallel/PetscHelper.cc b/AMDiS/src/parallel/PetscHelper.cc index 800709040db4ce7896f4671efabbd50191fe830d..2e560124afd7d585cc2f00ca4ff51f39d25dda3b 100644 --- a/AMDiS/src/parallel/PetscHelper.cc +++ b/AMDiS/src/parallel/PetscHelper.cc @@ -11,6 +11,7 @@ #include "parallel/PetscHelper.h" +#include "parallel/PetscSolver.h" #include "Global.h" namespace AMDiS { @@ -247,6 +248,25 @@ namespace AMDiS { MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY); } + + void setSolver(KSP ksp, + string kspPrefix, + KSPType kspType, + PCType pcType, + PetscReal rtol, + PetscReal atol, + PetscInt maxIt) + { + KSPSetType(ksp, kspType); + KSPSetTolerances(ksp, rtol, atol, PETSC_DEFAULT, maxIt); + if (kspPrefix != "") + KSPSetOptionsPrefix(ksp, kspPrefix.c_str()); + KSPSetFromOptions(ksp); + + PC pc; + KSPGetPC(ksp, &pc); + PCSetType(pc, pcType); + } } } diff --git a/AMDiS/src/parallel/PetscHelper.h b/AMDiS/src/parallel/PetscHelper.h index 9362aad873e912491ac7dce4ee25e7e6aaa3c0c0..e6ac70ea8ce6957d70d0139d6e55207080b9eec7 100644 --- a/AMDiS/src/parallel/PetscHelper.h +++ b/AMDiS/src/parallel/PetscHelper.h @@ -27,6 +27,7 @@ #include <map> #include <vector> #include <petsc.h> +#include "AMDiS_fwd.h" namespace AMDiS { @@ -89,6 +90,14 @@ namespace AMDiS { * \param[out] mat matrix of type MATAIJ, created inside this function. */ void matNestConvert(Mat matNest, Mat &mat); + + void setSolver(KSP ksp, + string kspPrefix, + KSPType kspType, + PCType pcType, + PetscReal rtol = PETSC_DEFAULT, + PetscReal atol = PETSC_DEFAULT, + PetscInt maxIt = PETSC_DEFAULT); } } diff --git a/AMDiS/src/parallel/PetscSolver.h b/AMDiS/src/parallel/PetscSolver.h index 463c5ac1365ba1a5e645647faad7fcb7ca3bc56a..0e75538bfd665041519259d5ab2c271aeb9923ed 100644 --- a/AMDiS/src/parallel/PetscSolver.h +++ b/AMDiS/src/parallel/PetscSolver.h @@ -150,6 +150,11 @@ namespace AMDiS { return dofMap; } + vector<const FiniteElemSpace*>& getComponentSpaces() + { + return componentSpaces; + } + protected: /** \brief * Copies between to PETSc vectors by using different index sets for the diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc index 8eeb8a71a2d6a503c34d30e7761cc40dd12fb095..6597dc2c57e437a568280c0d33d73de7e86c4a3f 100644 --- a/AMDiS/src/parallel/PetscSolverFeti.cc +++ b/AMDiS/src/parallel/PetscSolverFeti.cc @@ -10,7 +10,6 @@ // See also license.opensource.txt in the distribution. -#include "AMDiS.h" #include "MatrixVector.h" #include "parallel/PetscHelper.h" #include "parallel/PetscSolverFeti.h" diff --git a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc index 7700d26c447132a9b17f8f4b1f59cf784c6fad66..18e75fa99b630f5bf47064a046da8c90b1825bfe 100644 --- a/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc +++ b/AMDiS/src/parallel/PetscSolverGlobalMatrix.cc @@ -9,8 +9,8 @@ // // See also license.opensource.txt in the distribution. - -#include "AMDiS.h" +#include <mpi.h> +#include "DirichletBC.h" #include "parallel/PetscSolverGlobalMatrix.h" #include "parallel/StdMpi.h" #include "parallel/MpiHelper.h" @@ -904,4 +904,39 @@ namespace AMDiS { return subSolver; } + + void PetscSolverGlobalMatrix::setConstantNullSpace(KSP ksp, + int constFeSpace, + bool test) + { + Vec nullSpaceBasis; + VecDuplicate(getVecSolInterior(), &nullSpaceBasis); + + SystemVector basisVec("tmp", componentSpaces, componentSpaces.size(), true); + basisVec.set(0.0); + basisVec.getDOFVector(constFeSpace)->set(1.0); + + setDofVector(nullSpaceBasis, basisVec, true); + VecAssemblyBegin(nullSpaceBasis); + VecAssemblyEnd(nullSpaceBasis); + VecNormalize(nullSpaceBasis, PETSC_NULL); + + if (test) { + Vec tmp; + MatGetVecs(getMatInterior(), &tmp, PETSC_NULL); + MatMult(getMatInterior(), nullSpaceBasis, tmp); + PetscReal n; + VecNorm(tmp, NORM_2, &n); + MSG("NORM IS: %e\n", n); + VecDestroy(&tmp); + } + + + MatNullSpace matNullSpace; + MatNullSpaceCreate(mpiCommGlobal, PETSC_FALSE, 1, &nullSpaceBasis, &matNullSpace); + KSPSetNullSpace(ksp, matNullSpace); + MatNullSpaceDestroy(&matNullSpace); + } + + } diff --git a/AMDiS/src/parallel/PetscSolverGlobalMatrix.h b/AMDiS/src/parallel/PetscSolverGlobalMatrix.h index e35a3bd951029ca8b567a40273095fc21cb68750..b3ff065d8b4a7812c570a05739c0cfdf226ae9ec 100644 --- a/AMDiS/src/parallel/PetscSolverGlobalMatrix.h +++ b/AMDiS/src/parallel/PetscSolverGlobalMatrix.h @@ -130,6 +130,8 @@ namespace AMDiS { PetscSolver* createSubSolver(int component, string kspPrefix); + void setConstantNullSpace(KSP ksp, int constFeSpace, bool test = false); + protected: bool zeroStartVector; diff --git a/AMDiS/src/parallel/PetscSolverNavierStokes.cc b/AMDiS/src/parallel/PetscSolverNavierStokes.cc index 070c7f471220eeefd1ef6be590e3a395c66b66d8..7bfd5d6565adc5a0ca513416fae8b96e1117fac5 100644 --- a/AMDiS/src/parallel/PetscSolverNavierStokes.cc +++ b/AMDiS/src/parallel/PetscSolverNavierStokes.cc @@ -12,98 +12,22 @@ #include "parallel/PetscSolverNavierStokes.h" +#include "parallel/PetscHelper.h" namespace AMDiS { using namespace std; - PetscErrorCode pcNs(PC pc, Vec x, Vec y) + PetscErrorCode pcSchurShell(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); + NavierStokesSchurData* data = static_cast<NavierStokesSchurData*>(ctx); - 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; - MatShellGetContext(mat, &ctx); - MatShellNavierStokesSchur* data = static_cast<MatShellNavierStokesSchur*>(ctx); - - switch (data->solverMode) { - case 0: - { - Vec vec0, vec1; - VecDuplicate(x, &vec0); - MatGetVecs(data->A00, &vec1, PETSC_NULL); - - MatMult(data->A11, x, y); - MatMult(data->A01, x, vec1); - KSPSolve(data->kspVelocity, vec1, vec1); - MatMult(data->A10, vec1, y); - VecAYPX(y, -1.0, vec0); - - VecDestroy(&vec0); - VecDestroy(&vec1); - } - break; - case 1: - { - Vec vec0, vec1; - VecDuplicate(x, &vec0); - VecDuplicate(x, &vec1); - - // KSPSolve(data->kspLaplace, x, vec0); - // MatMult(data->matConDif, vec0, vec1); - //KSPSolve(data->kspMass, vec0, y); - VecSet(y, 0.0); - - VecDestroy(&vec0); - VecDestroy(&vec1); - } - break; - default: - ERROR_EXIT("Wrong solver mode %d\n", data->solverMode); - } + KSPSolve(data->kspLaplace, x, y); + MatMult(data->matConDif, y, x); + KSPSolve(data->kspMass, x, y); } @@ -111,7 +35,10 @@ namespace AMDiS { : PetscSolverGlobalMatrix(name), pressureComponent(-1), massMatrixSolver(NULL), - laplaceMatrixSolver(NULL) + laplaceMatrixSolver(NULL), + nu(NULL), + invTau(NULL), + solution(NULL) { Parameters::get(initFileStr + "->stokes->pressure component", pressureComponent); @@ -127,32 +54,14 @@ namespace AMDiS { { FUNCNAME("PetscSolverNavierStokes::initSolver()"); + // Create FGMRES based outer solver KSPCreate(mpiCommGlobal, &ksp); - KSPSetOperators(ksp, getMatInterior(), getMatInterior(), - SAME_NONZERO_PATTERN); - KSPSetTolerances(ksp, 0.0, 1e-8, PETSC_DEFAULT, PETSC_DEFAULT); - KSPSetType(ksp, KSPGMRES); - KSPSetOptionsPrefix(ksp, "ns_"); - KSPSetFromOptions(ksp); + KSPSetOperators(ksp, getMatInterior(), getMatInterior(), SAME_NONZERO_PATTERN); KSPMonitorSet(ksp, KSPMonitorTrueResidualNorm, PETSC_NULL, PETSC_NULL); + petsc_helper::setSolver(ksp, "ns_", KSPFGMRES, PCNONE, 1e-6, 1e-8, 100); - - // === Create null space information. === - - Vec nullSpaceBasis; - VecDuplicate(getVecSolInterior(), &nullSpaceBasis); - - SystemVector basisVec("tmp", componentSpaces, componentSpaces.size(), true); - basisVec.set(0.0); - basisVec.getDOFVector(pressureComponent)->set(1.0); - - setDofVector(nullSpaceBasis, basisVec, true); - VecAssemblyBegin(nullSpaceBasis); - VecAssemblyEnd(nullSpaceBasis); - VecNormalize(nullSpaceBasis, PETSC_NULL); - - MatNullSpace matNullSpace; - MatNullSpaceCreate(mpiCommGlobal, PETSC_FALSE, 1, &nullSpaceBasis, &matNullSpace); + // Create null space information. + setConstantNullSpace(ksp, pressureComponent); } @@ -160,35 +69,45 @@ namespace AMDiS { { FUNCNAME("PetscSolverNavierStokes::initPreconditioner()"); + vector<int> velocityComponents; + velocityComponents.push_back(0); + velocityComponents.push_back(1); - 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); + 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); + + petsc_helper::setSolver(kspVelocity, "", KSPRICHARDSON, PCHYPRE, 0.0, 1e-14, 1); + + KSPSetType(kspSchur, KSPPREONLY); PC pcSub; - KSPGetPC(matShellContext.kspVelocity, &pcSub); - PCSetType(pcSub, PCLU); - PCFactorSetMatSolverPackage(pcSub, MATSOLVERMUMPS); - + KSPGetPC(kspSchur, &pcSub); + PCSetType(pcSub, PCSHELL); + PCShellSetApply(pcSub, pcSchurShell); + PCShellSetContext(pcSub, &matShellContext); - // === Mass matrix solver === + MatNullSpace matNullSpace; + MatNullSpaceCreate(mpiCommGlobal, PETSC_TRUE, 0, PETSC_NULL, &matNullSpace); + KSPSetNullSpace(kspSchur, matNullSpace); + MatNullSpaceDestroy(&matNullSpace); - MSG("Initialize mass matrix solver ...\n"); + + // === Mass matrix solver === const FiniteElemSpace *pressureFeSpace = componentSpaces[pressureComponent]; DOFMatrix massMatrix(pressureFeSpace, pressureFeSpace); @@ -196,49 +115,37 @@ namespace AMDiS { Simple_ZOT zot; massOp.addTerm(&zot); massMatrix.assembleOperator(massOp); - massMatrixSolver = createSubSolver(pressureComponent, "mass_"); massMatrixSolver->fillPetscMatrix(&massMatrix); - MSG("... OK!\n"); - // === Laplace matrix solver === - MSG("Initialize laplace matrix solver ...\n"); - DOFMatrix laplaceMatrix(pressureFeSpace, pressureFeSpace); Operator laplaceOp(pressureFeSpace, pressureFeSpace); Simple_SOT sot; laplaceOp.addTerm(&sot); laplaceMatrix.assembleOperator(laplaceOp); - laplaceMatrixSolver = createSubSolver(pressureComponent, "laplace_"); laplaceMatrixSolver->fillPetscMatrix(&laplaceMatrix); - MSG("... OK!\n"); - // === Create convection-diffusion operator === - MSG("Initialize pressure convection-diffusion operator ...\n"); - - double timestep = 1.0; - Parameters::get("navierstokes->adapt->timestep", timestep); - timestep = 1.0 / timestep; - - double nu = 0.01; - Parameters::get("nu", nu); + DOFVector<double> vx(pressureFeSpace, "vx"); + DOFVector<double> vy(pressureFeSpace, "vy"); + vx.interpol(solution->getDOFVector(0)); + vy.interpol(solution->getDOFVector(1)); DOFMatrix conDifMatrix(pressureFeSpace, pressureFeSpace); Operator conDifOp(pressureFeSpace, pressureFeSpace); - Simple_ZOT conDif0(timestep); + Simple_ZOT conDif0(*invTau); conDifOp.addTerm(&conDif0); - Simple_SOT conDif1(nu); + Simple_SOT conDif1(*nu); conDifOp.addTerm(&conDif1); - Vector_FOT conDif2(0); + VecAtQP_FOT conDif2(&vx, &idFct, 0); conDifOp.addTerm(&conDif2, GRD_PHI); - Vector_FOT conDif3(1); + VecAtQP_FOT conDif3(&vy, &idFct, 1); conDifOp.addTerm(&conDif3, GRD_PHI); conDifMatrix.assembleOperator(conDifOp); @@ -246,87 +153,16 @@ namespace AMDiS { conDifMatrixSolver = createSubSolver(pressureComponent, "condif_"); conDifMatrixSolver->fillPetscMatrix(&conDifMatrix); - MSG("... OK!\n"); + + // === Setup solver === matShellContext.kspMass = massMatrixSolver->getSolver(); 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); - PCSetType(pcSub, PCLU); - PCFactorSetMatSolverPackage(pcSub, MATSOLVERMUMPS); - 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 + petsc_helper::setSolver(matShellContext.kspMass, "", KSPCG, PCJACOBI, 0.0, 1e-14, 2); + petsc_helper::setSolver(matShellContext.kspLaplace, "", KSPRICHARDSON, PCHYPRE, 0.0, 1e-14, 1); } + } diff --git a/AMDiS/src/parallel/PetscSolverNavierStokes.h b/AMDiS/src/parallel/PetscSolverNavierStokes.h index 302f2b7037130baf3dba7cb9498f0cdcd4d2e96c..354e235a9b6a89a59513367f4df9aaa73029ce53 100644 --- a/AMDiS/src/parallel/PetscSolverNavierStokes.h +++ b/AMDiS/src/parallel/PetscSolverNavierStokes.h @@ -29,32 +29,38 @@ namespace AMDiS { using namespace std; - struct MatShellNavierStokesSchur { - int solverMode; - - // === Data for mode 0 (solve the schur complement directly) === - - Mat A00, A01, A10, A11; - - KSP kspVelocity; - - - // === Data for mode 1 === - + struct NavierStokesSchurData { KSP kspMass, kspLaplace; Mat matConDif; - - - - IS isVelocity, isPressure; }; class PetscSolverNavierStokes : public PetscSolverGlobalMatrix { + private: + class IdFct : public AbstractFunction<double, double> + { + public: + IdFct() + : AbstractFunction<double, double>(0) + {} + + double operator()(const double& x) const + { + return x; + } + }; + public: PetscSolverNavierStokes(string name); + void setStokesData(double *nuPtr, double *invTauPtr, SystemVector *vec) + { + nu = nuPtr; + invTau = invTauPtr; + solution = vec; + } + protected: void initSolver(KSP &ksp); @@ -65,7 +71,13 @@ namespace AMDiS { PetscSolver *massMatrixSolver, *laplaceMatrixSolver, *conDifMatrixSolver; - MatShellNavierStokesSchur matShellContext; + NavierStokesSchurData matShellContext; + + double *nu, *invTau; + + SystemVector* solution; + + IdFct idFct; }; }