// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // == http://www.amdis-fem.org == // == == // ============================================================================ // // Software License for AMDiS // // Copyright (c) 2010 Dresden University of Technology // All rights reserved. // Authors: Simon Vey, Thomas Witkowski et al. // // This file is part of AMDiS // // See also license.opensource.txt in the distribution. /** \file PetscSolver.h */ #ifndef AMDIS_PETSC_SOLVER_H #define AMDIS_PETSC_SOLVER_H #include #include #include #include "AMDiS_fwd.h" #include "Global.h" #include "Initfile.h" #include "DOFMatrix.h" #include "parallel/MeshDistributor.h" #include #include #include #include namespace AMDiS { using namespace std; class PetscSolver { public: PetscSolver(); virtual ~PetscSolver() {} void setMeshDistributor(MeshDistributor *m, MPI::Intracomm mpiComm0, MPI::Intracomm mpiComm1) { meshDistributor = m; mpiCommGlobal = mpiComm0; mpiCommLocal = mpiComm1; mpiRank = mpiCommGlobal.Get_rank(); } void setLevel(int l) { subdomainLevel = l; } void setDofMapping(ParallelDofMapping *interiorDofs, ParallelDofMapping *coarseDofs = NULL); /** \brief * Create a PETSc matrix. The given DOF matrices are used to create the nnz * structure of the PETSc matrix and the values are transfered to it. * * \param[in] mat */ virtual void fillPetscMatrix(Matrix *mat) = 0; /** \brief * Create a PETSc vector and fills it with the rhs values of the system. * * \param[in] vec */ virtual void fillPetscRhs(SystemVector *vec) = 0; /// Use PETSc to solve the linear system of equations virtual void solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo) = 0; virtual void solve(Vec &rhs, Vec &sol); virtual void solveGlobal(Vec &rhs, Vec &sol); /// Destroys all matrix data structures. virtual void destroyMatrixData() = 0; /// Detroys all vector data structures. virtual void destroyVectorData() = 0; virtual Flag getBoundaryDofRequirement() { return 0; } KSP getSolver() { return kspInterior; } PC getPc() { return pcInterior; } void setKspPrefix(std::string s) { kspPrefix = s; } void setRemoveRhsNullspace(bool b) { removeRhsNullspace = b; } /// Adds a new vector to the basis of the operator's nullspace. void addNullspaceVector(SystemVector *vec) { nullspace.push_back(vec); } /// Sets the nullspace to be constant for some specific components. void setConstantNullspace(vector &components) { constNullspaceComponent = components; } /// Sets the nullspace to be constant for a specific component. void setConstantNullspace(int component) { constNullspaceComponent.clear(); constNullspaceComponent.push_back(component); } inline bool isCoarseSpace(const FiniteElemSpace *feSpace, DegreeOfFreedom dof) { FUNCNAME("PetscSolver::isCoarseSpace()"); if (coarseSpaceMap == NULL) return false; return (*coarseSpaceMap)[feSpace].isSet(dof); } inline Vec& getRhsCoarseSpace() { FUNCNAME("PetscSolver::getRhsCoarseSpace()"); TEST_EXIT_DBG(coarseSpaceMap) ("Subdomain solver does not contain a coarse space!\n"); return rhsCoarseSpace; } inline Vec& getRhsInterior() { return rhsInterior; } inline Mat& getMatIntInt() { return matIntInt; } inline Mat& getMatCoarseCoarse() { FUNCNAME("PetscSolver::getMatCoarseCoarse()"); TEST_EXIT_DBG(coarseSpaceMap) ("Subdomain solver does not contain a coarse space!\n"); return matCoarseCoarse; } inline Mat& getMatIntCoarse() { FUNCNAME("PetscSolver::getMatIntCoarse()"); TEST_EXIT_DBG(coarseSpaceMap) ("Subdomain solver does not contain a coarse space!\n"); return matIntCoarse; } inline Mat& getMatCoarseInt() { FUNCNAME("PetscSolver::getMatCoarseInt()"); TEST_EXIT_DBG(coarseSpaceMap) ("Subdomain solver does not contain a coarse space!\n"); return matCoarseInt; } protected: /** \brief * Copies between to PETSc vectors by using different index sets for the * origin and the destination vectors. * * \param[in] originVec The PETSc vector from which we copy from. * \param[out] destVec The PETSc vector we copy too. * \param[in] originIndex Set of global indices referring to the * origin vector. * \param[in] destIndex Set of global indices referring to the * destination vector. */ void copyVec(Vec& originVec, Vec& destVec, vector& originIndex, vector& destIndex); /// Checks if all given FE spaces are handled by the mesh distributor. void checkFeSpaces(vector& feSpaces); /// Returns a vector with the FE spaces of each row in the matrix. Thus, the /// resulting vector may contain the same FE space multiple times. vector getFeSpaces(Matrix *mat); /// Returns a vector with the FE spaces of all components of a system vector. vector getFeSpaces(SystemVector *vec); void updateSubdomainData(); protected: MeshDistributor *meshDistributor; int subdomainLevel; int rStartInterior; int nGlobalOverallInterior; ParallelDofMapping *interiorMap; ParallelDofMapping* coarseSpaceMap; int mpiRank; MPI::Intracomm mpiCommGlobal; MPI::Intracomm mpiCommLocal; /// Petsc's matrix structure. Mat matIntInt, matCoarseCoarse, matIntCoarse, matCoarseInt; /// PETSc's vector structures for the rhs vector, the solution vector and a /// temporary vector for calculating the final residuum. Vec rhsInterior; Vec rhsCoarseSpace; /// PETSc solver object KSP kspInterior; /// PETSc preconditioner object PC pcInterior; /// A set of vectors that span the null space of the operator. vector nullspace; /// KSP database prefix string kspPrefix; /// If true, the constant null space is projected out of the RHS vector. It /// depends on the specific PETSc solver if it considers this value. bool removeRhsNullspace; bool hasConstantNullspace; vector constNullspaceComponent; }; } // namespace AMDiS #endif