Commit 2f5be996 by Sebastian Aland

### PetscSolverCahnHilliard geht jetzt auch mit diffuse domain

parent 6ee1c6b6
 ... @@ -16,139 +16,189 @@ ... @@ -16,139 +16,189 @@ #include "parallel/PetscSolverGlobalMatrix.h" #include "parallel/PetscSolverGlobalMatrix.h" namespace AMDiS { namespace AMDiS { class Multiplier: public AbstractFunction { public: Multiplier(double d_) : AbstractFunction(2),d(d_) {}; double operator()(const double& x) const { return d*x; } protected: double d; }; using namespace std; using namespace std; /// solve Cahn-Hilliard Preconditioner /// solve Cahn-Hilliard Preconditioner PetscErrorCode pcChShell(PC pc, Vec b, Vec x) // solve Px=b PetscErrorCode pcChShell(PC pc, Vec b, Vec x) // solve Px=b {FUNCNAME("PCApply()"); {FUNCNAME("PCApply()"); void *ctx; void *ctx; PCShellGetContext(pc, &ctx); PCShellGetContext(pc, &ctx); CahnHilliardData* data = static_cast(ctx); CahnHilliardData* data = static_cast(ctx); Vec b1, b2, x1, x2; Vec b1, b2, x1, x2; VecNestGetSubVec(b, 0, &b1); VecNestGetSubVec(b, 0, &b1); VecNestGetSubVec(b, 1, &b2); VecNestGetSubVec(b, 1, &b2); VecNestGetSubVec(x, 0, &x1); VecNestGetSubVec(x, 0, &x1); VecNestGetSubVec(x, 1, &x2); VecNestGetSubVec(x, 1, &x2); Vec y1, y2; Vec y1, y2; VecDuplicate(b1, &y1); VecDuplicate(b1, &y1); VecDuplicate(b2, &y2); VecDuplicate(b2, &y2); // MatGetDiagonal(data->matM, y2); // MatGetDiagonal(data->matM, y2); // VecReciprocal(y2); // VecReciprocal(y2); // VecPointwiseMult(y1, y2, b1); // VecPointwiseMult(y1, y2, b1); KSPSolve(data->kspMass, b1, y1); // M*y1 = b1 KSPSolve(data->kspMass, b1, y1); // M*y1 = b1 MatMultAdd(data->matMinusDeltaK, y1, b2, x1); // -> x1 := b2-delta*K*y1 MatMultAdd(data->matMinusDeltaK, y1, b2, x1); // -> x1 := b2-delta*K*y1 KSPSolve(data->kspLaplace, x1, y2); // (M+eps*sqrt(delta))*y2 = x1 KSPSolve(data->kspLaplace, x1, y2); // (M+eps*sqrt(delta))*y2 = x1 MatMult(data->matM, y2, x1); // x1 := M*y2 MatMult(data->matM, y2, x1); // x1 := M*y2 KSPSolve(data->kspLaplace, x1, x2); // (M+eps*sqrt(delta))*x2 = x1 KSPSolve(data->kspLaplace, x1, x2); // (M+eps*sqrt(delta))*x2 = x1 double factor = (*data->eps)/sqrt(*data->delta); double factor = (*data->eps)/sqrt(*data->delta); VecCopy(x2, x1); // x1 := x2 VecCopy(x2, x1); // x1 := x2 VecAXPBYPCZ(x1, 1.0, factor, -factor, y1, y2); // x1 = 1*y1 + factor*y2 - factor*x1 VecAXPBYPCZ(x1, 1.0, factor, -factor, y1, y2); // x1 = 1*y1 + factor*y2 - factor*x1 VecDestroy(&y1); VecDestroy(&y1); VecDestroy(&y2); VecDestroy(&y2); } } PetscSolverCahnHilliard::PetscSolverCahnHilliard(string name, double *epsPtr, double *deltaPtr) PetscSolverCahnHilliard::PetscSolverCahnHilliard(string name, double *epsPtr, double *deltaPtr) : PetscSolverGlobalBlockMatrix(name), : PetscSolverGlobalBlockMatrix(name), massMatrixSolver(NULL), massMatrixSolver(NULL), laplaceMatrixSolver(NULL), laplaceMatrixSolver(NULL), deltaKMatrixSolver(NULL), deltaKMatrixSolver(NULL), useOldInitialGuess(false), useOldInitialGuess(false), eps(epsPtr), eps(epsPtr), delta(deltaPtr) { delta(deltaPtr) { Parameters::get(initFileStr + "->use old initial guess", useOldInitialGuess); Parameters::get(initFileStr + "->use old initial guess", useOldInitialGuess); } } void PetscSolverCahnHilliard::solvePetscMatrix(SystemVector &vec, void PetscSolverCahnHilliard::solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo) AdaptInfo *adaptInfo) { { FUNCNAME("PetscSolverCahnHilliard::solvePetscMatrix()"); FUNCNAME("PetscSolverCahnHilliard::solvePetscMatrix()"); /* if (useOldInitialGuess) { /* if (useOldInitialGuess) { VecSet(getVecSolInterior(), 0.0); if (getVecSolInterior()) {VecSet(getVecSolInterior(), 0.0); for (int i = 0; i < solution->getSize(); i++) for (int i = 0; i < solution->getSize(); i++) { { Vec tmp; Vec tmp; VecNestGetSubVec(getVecSolInterior(), i, &tmp); VecNestGetSubVec(getVecSolInterior(), i, &tmp); setDofVector(tmp, solution->getDOFVector(i)); setDofVector(tmp, solution->getDOFVector(i)); } } vecSolAssembly(); vecSolAssembly(); KSPSetInitialGuessNonzero(kspInterior, PETSC_TRUE); KSPSetInitialGuessNonzero(kspInterior, PETSC_TRUE); } } */ KSPSetInitialGuessNonzero(kspInterior, PETSC_TRUE); KSPSetInitialGuessNonzero(kspInterior, PETSC_TRUE); }*/ PetscSolverGlobalBlockMatrix::solvePetscMatrix(vec, adaptInfo); PetscSolverGlobalBlockMatrix::solvePetscMatrix(vec, adaptInfo); } } void PetscSolverCahnHilliard::initSolver(KSP &ksp) void PetscSolverCahnHilliard::initSolver(KSP &ksp) { { FUNCNAME("PetscSolverCahnHilliard::initSolver()"); FUNCNAME("PetscSolverCahnHilliard::initSolver()"); // Create FGMRES based outer solver // Create FGMRES based outer solver KSPCreate(meshDistributor->getMpiComm(0), &ksp); KSPCreate(meshDistributor->getMpiComm(0), &ksp); KSPSetOperators(ksp, getMatInterior(), getMatInterior(), SAME_NONZERO_PATTERN); KSPSetOperators(ksp, getMatInterior(), getMatInterior(), SAME_NONZERO_PATTERN); KSPMonitorSet(ksp, KSPMonitorTrueResidualNorm, PETSC_NULL, PETSC_NULL); KSPMonitorSet(ksp, KSPMonitorTrueResidualNorm, PETSC_NULL, PETSC_NULL); petsc_helper::setSolver(ksp, "ch_", KSPFGMRES, PCNONE, 1e-6, 1e-8, 1000); petsc_helper::setSolver(ksp, "ch_", KSPFGMRES, PCNONE, 1e-6, 1e-8, 1000); KSPSetFromOptions(ksp); KSPSetFromOptions(ksp); } } void PetscSolverCahnHilliard::initPreconditioner(PC pc) void PetscSolverCahnHilliard::initPreconditioner(PC pc) { { FUNCNAME("PetscSolverCahnHilliard::initPreconditioner()"); FUNCNAME("PetscSolverCahnHilliard::initPreconditioner()"); MSG("PetscSolverCahnHilliard::initPreconditioner()\n"); MSG("PetscSolverCahnHilliard::initPreconditioner()\n"); // KSPSetUp(kspInterior); // KSPSetUp(kspInterior); PCSetType(pc, PCSHELL); PCSetType(pc, PCSHELL); PCShellSetApply(pc, pcChShell); PCShellSetApply(pc, pcChShell); PCShellSetContext(pc, &matShellContext); PCShellSetContext(pc, &matShellContext); const FiniteElemSpace *feSpace = componentSpaces[0]; const FiniteElemSpace *feSpace = componentSpaces[0]; // === matrix M === // === matrix M === DOFMatrix massMatrix(feSpace, feSpace); Operator massOp(feSpace, feSpace); Simple_ZOT zot; massOp.addTerm(&zot); massMatrix.assembleOperator(massOp); massMatrixSolver = createSubSolver(0, "mass_"); massMatrixSolver->fillPetscMatrix(&massMatrix); // === matrix (M + eps*sqrt(delta)*K) === DOFMatrix laplaceMatrix(feSpace, feSpace); DOFMatrix laplaceMatrix(feSpace, feSpace); Operator laplaceOp(feSpace, feSpace); Operator laplaceOp(feSpace, feSpace); laplaceOp.addTerm(&zot); // M Simple_SOT sot2((*eps)*sqrt(*delta)); laplaceOp.addTerm(&sot2); // eps*sqrt(delta)*K laplaceMatrix.assembleOperator(laplaceOp); laplaceMatrixSolver = createSubSolver(0, "laplace_"); laplaceMatrixSolver->fillPetscMatrix(&laplaceMatrix); // === matrix (-delta*K) === DOFMatrix massMatrix(feSpace, feSpace); Operator massOp(feSpace, feSpace); DOFMatrix deltaKMatrix(feSpace, feSpace); DOFMatrix deltaKMatrix(feSpace, feSpace); Operator laplaceOp2(feSpace, feSpace); Operator laplaceOp2(feSpace, feSpace); Simple_SOT sot(-(*delta)); laplaceOp2.addTerm(&sot); // -delta*K if (phase) deltaKMatrix.assembleOperator(laplaceOp2); { deltaKMatrixSolver = createSubSolver(0, "laplace2_"); VecAtQP_ZOT zot(phase, NULL); deltaKMatrixSolver->fillPetscMatrix(&deltaKMatrix); massOp.addTerm(&zot); laplaceOp.addTerm(&zot); // M VecAtQP_SOT sot2(phase, new Multiplier((*eps)*sqrt(*delta))); laplaceOp.addTerm(&sot2); // eps*sqrt(delta)*K VecAtQP_SOT sot(phase, new Multiplier(-(*delta))); laplaceOp2.addTerm(&sot); // -delta*K massMatrix.assembleOperator(massOp); massMatrixSolver = createSubSolver(0, "mass_"); massMatrixSolver->fillPetscMatrix(&massMatrix); // === matrix (M + eps*sqrt(delta)*K) === laplaceMatrix.assembleOperator(laplaceOp); laplaceMatrixSolver = createSubSolver(0, "laplace_"); laplaceMatrixSolver->fillPetscMatrix(&laplaceMatrix); // === matrix (-delta*K) === deltaKMatrix.assembleOperator(laplaceOp2); deltaKMatrixSolver = createSubSolver(0, "laplace2_"); deltaKMatrixSolver->fillPetscMatrix(&deltaKMatrix); } else { Simple_ZOT zot; massOp.addTerm(&zot); laplaceOp.addTerm(&zot); // M Simple_SOT sot2((*eps)*sqrt(*delta)); laplaceOp.addTerm(&sot2); // eps*sqrt(delta)*K Simple_SOT sot(-(*delta)); laplaceOp2.addTerm(&sot); // -delta*K massMatrix.assembleOperator(massOp); massMatrixSolver = createSubSolver(0, "mass_"); massMatrixSolver->fillPetscMatrix(&massMatrix); // === matrix (M + eps*sqrt(delta)*K) === laplaceMatrix.assembleOperator(laplaceOp); laplaceMatrixSolver = createSubSolver(0, "laplace_"); laplaceMatrixSolver->fillPetscMatrix(&laplaceMatrix); // === matrix (-delta*K) === deltaKMatrix.assembleOperator(laplaceOp2); deltaKMatrixSolver = createSubSolver(0, "laplace2_"); deltaKMatrixSolver->fillPetscMatrix(&deltaKMatrix); } // === Setup solver === // === Setup solver === matShellContext.kspMass = massMatrixSolver->getSolver(); matShellContext.kspMass = massMatrixSolver->getSolver(); ... @@ -159,43 +209,43 @@ namespace AMDiS { ... @@ -159,43 +209,43 @@ namespace AMDiS { matShellContext.delta = delta; matShellContext.delta = delta; matShellContext.mpiCommGlobal= &(meshDistributor->getMpiComm(0)); matShellContext.mpiCommGlobal= &(meshDistributor->getMpiComm(0)); petsc_helper::setSolver(matShellContext.kspMass, "", KSPCG, PCJACOBI, 0.0, 1e-14, 2); petsc_helper::setSolver(matShellContext.kspMass, "", KSPCG, PCJACOBI, 0.0, 1e-14, 2); // petsc_helper::setSolver(matShellContext.kspMass, "mass_", KSPRICHARDSON, PCLU, 0.0, 1e-14, 1); // petsc_helper::setSolver(matShellContext.kspMass, "mass_", KSPRICHARDSON, PCLU, 0.0, 1e-14, 1); // { // { // PC pc; // PC pc; // KSPGetPC(matShellContext.kspMass, &pc); // KSPGetPC(matShellContext.kspMass, &pc); // PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS); // PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS); // } // } petsc_helper::setSolver(matShellContext.kspLaplace, "laplace_", KSPRICHARDSON, PCHYPRE, 0.0, 1e-14, 1); petsc_helper::setSolver(matShellContext.kspLaplace, "laplace_", KSPRICHARDSON, PCHYPRE, 0.0, 1e-14, 1); // petsc_helper::setSolver(matShellContext.kspLaplace, "laplace_", KSPRICHARDSON, PCLU, 0.0, 1e-14, 1); // petsc_helper::setSolver(matShellContext.kspLaplace, "laplace_", KSPRICHARDSON, PCLU, 0.0, 1e-14, 1); // { // { // PC pc; // PC pc; // KSPGetPC(matShellContext.kspLaplace, &pc); // KSPGetPC(matShellContext.kspLaplace, &pc); // PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS); // PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS); // } // } PCSetFromOptions(pc); PCSetFromOptions(pc); } } PetscSolver* PetscSolverCahnHilliard::createSubSolver(int component, PetscSolver* PetscSolverCahnHilliard::createSubSolver(int component, string kspPrefix) string kspPrefix) { { FUNCNAME("PetscSolverCahnHilliard::createSubSolver()"); FUNCNAME("PetscSolverCahnHilliard::createSubSolver()"); vector fe; vector fe; fe.push_back(componentSpaces[component]); fe.push_back(componentSpaces[component]); PetscSolver* subSolver = new PetscSolverGlobalMatrix(""); PetscSolver* subSolver = new PetscSolverGlobalMatrix(""); subSolver->setKspPrefix(kspPrefix.c_str()); subSolver->setKspPrefix(kspPrefix.c_str()); subSolver->setMeshDistributor(meshDistributor, 0); subSolver->setMeshDistributor(meshDistributor, 0); subSolver->init(fe, fe); subSolver->init(fe, fe); ParallelDofMapping &subDofMap = subSolver->getDofMap(); ParallelDofMapping &subDofMap = subSolver->getDofMap(); subDofMap[0] = dofMap[component]; subDofMap[0] = dofMap[component]; subDofMap.update(); subDofMap.update(); return subSolver; return subSolver; } } ... @@ -206,21 +256,21 @@ namespace AMDiS { ... @@ -206,21 +256,21 @@ namespace AMDiS { massMatrixSolver->destroyMatrixData(); massMatrixSolver->destroyMatrixData(); laplaceMatrixSolver->destroyMatrixData(); laplaceMatrixSolver->destroyMatrixData(); deltaKMatrixSolver->destroyMatrixData(); deltaKMatrixSolver->destroyMatrixData(); massMatrixSolver->destroyVectorData(); massMatrixSolver->destroyVectorData(); laplaceMatrixSolver->destroyVectorData(); laplaceMatrixSolver->destroyVectorData(); deltaKMatrixSolver->destroyVectorData(); deltaKMatrixSolver->destroyVectorData(); delete massMatrixSolver; delete massMatrixSolver; massMatrixSolver = NULL; massMatrixSolver = NULL; delete laplaceMatrixSolver; delete laplaceMatrixSolver; laplaceMatrixSolver = NULL; laplaceMatrixSolver = NULL; delete deltaKMatrixSolver; delete deltaKMatrixSolver; deltaKMatrixSolver = NULL; deltaKMatrixSolver = NULL; } } } }
 ... @@ -58,11 +58,12 @@ namespace AMDiS { ... @@ -58,11 +58,12 @@ namespace AMDiS { PetscSolverCahnHilliard(string name, double *epsPtr = NULL, double *deltaPtr = NULL); PetscSolverCahnHilliard(string name, double *epsPtr = NULL, double *deltaPtr = NULL); void setChData(double *epsPtr, double *deltaPtr, SystemVector* vec) void setChData(double *epsPtr, double *deltaPtr, SystemVector* vec, DOFVector *p=NULL) { { eps = epsPtr; eps = epsPtr; delta = deltaPtr; delta = deltaPtr; solution = vec; solution = vec; phase = p; } } protected: protected: ... @@ -83,6 +84,8 @@ namespace AMDiS { ... @@ -83,6 +84,8 @@ namespace AMDiS { bool useOldInitialGuess; bool useOldInitialGuess; SystemVector* solution; SystemVector* solution; DOFVector *phase; double *eps, *delta; double *eps, *delta; }; }; ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment