// ============================================================================ // == == // == 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 PetscSolverFeti.h */ #include #include "parallel/MpiHelper.h" #include "parallel/PetscSolver.h" #include "parallel/PetscSolverFetiStructs.h" #include "parallel/ParallelDofMapping.h" #include "parallel/ParallelTypes.h" #include "parallel/SubDomainSolver.h" #ifndef AMDIS_PETSC_SOLVER_FETI_H #define AMDIS_PETSC_SOLVER_FETI_H namespace AMDiS { using namespace std; /** \brief * FETI-DP implementation based on PETSc. */ class PetscSolverFeti : public PetscSolver { public: PetscSolverFeti(); /// Assemble the sequentially created matrices to the global matrices /// required by the FETI-DP method. void fillPetscMatrix(Matrix *mat); /// Assembles the global rhs vectors from the sequentially created ones. void fillPetscRhs(SystemVector *vec); /// Solve the system using FETI-DP method. void solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo); /// Destroys all matrix data structures. void destroyMatrixData(); /// Detroys all vector data structures. void destroyVectorData(); /// Returns flags to denote which information of the boundary DOFs are /// required by the FETI-DP solver. Flag getBoundaryDofRequirement() { return MeshDistributor::BOUNDARY_SUBOBJ_SORTED | MeshDistributor::BOUNDARY_FILL_INFO_SEND_DOFS | MeshDistributor::BOUNDARY_FILL_INFO_RECV_DOFS; } /// Initialization of the data structures with a given list of the FE /// spaces of all components. void initialize(vector feSpaces); /// After mesh changes, or if the solver is called the first time, this /// function creates all information about primal nodes, dual nodes and /// lagrange constraints. void createFetiData(); int getNumberOfPrimals() { return primalDofMap.getOverallDofs(); } int getNumberOfDuals() { return dualDofMap.getOverallDofs(); } protected: /// Defines which boundary nodes are primal. Creates global index of /// the primal variables. void createPrimals(const FiniteElemSpace *feSpace); /// Defines the set of dual variables and creates the global index of // dual variables. void createDuals(const FiniteElemSpace *feSpace); /// Create Lagrange multiplier variables corresponding to the dual /// variables. void createLagrange(const FiniteElemSpace *feSpace); /// Creates a global index of the B variables. void createIndexB(const FiniteElemSpace *feSpace); /// Creates the Lagrange multiplier constraints and assembles them /// to \ref mat_lagrange. void createMatLagrange(vector &feSpaces); /// Creates PETSc KSP solver object for solving the Schur complement /// system on the primal variables, \ref ksp_schur_primal void createSchurPrimalKsp(vector &feSpaces); /// Destroys PETSc KSP solver object \ref ksp_schur_primal void destroySchurPrimalKsp(); /// Creates PETSc KSP solver object for the FETI-DP operator, \ref ksp_feti void createFetiKsp(vector &feSpaces); /// Destroys FETI-DP operator, \ref ksp_feti void destroyFetiKsp(); /** \brief * Recovers AMDiS solution vector from PETSc's solution vectors of the * FETI-DP system. First, the B variables can locally be copied to the * corresponding entries in the DOF vectors. The primal variable must * be communicated such that all ranks sharing a primal get a copy of * the corresponding value. * * \param[in] vec_sol_b Global PETSc vector of the solution of * the B variables. * \param[in] vec_sol_primal Global PETSc vector of the solution of * the primal variables. * \param[out] vec SystemVector containing all solution * DOF vectors. */ void recoverSolution(Vec &vec_sol_b, Vec &vec_sol_primal, SystemVector &vec); /** \brief * Solves the FETI-DP system globally, thus without reducing it to the * Lagrange multipliers. This should be used for debugging only to test * if the FETI-DP system is setup correctly. * * \param[out] vec Solution DOF vectors. */ void solveFetiMatrix(SystemVector &vec); /** \brief * Solves the FETI-DP system with reducing it first to the Lagrange * multipliers. This is what one expects when using the FETI-DP methid :) * * \param[out] vec Solution DOF vectors. */ void solveReducedFetiMatrix(SystemVector &vec); void resetStatistics(); void printStatistics(); /// Checks whether a given DOF in a given FE space is a primal DOF. inline bool isPrimal(const FiniteElemSpace *feSpace, DegreeOfFreedom dof) { return primalDofMap[feSpace].isSet(dof); } /// Checks whether a given DOF in a give FE space is a dual DOF. inline bool isDual(const FiniteElemSpace *feSpace, DegreeOfFreedom dof) { return dualDofMap[feSpace].isSet(dof); } protected: /// Mapping from primal DOF indices to a global index of primals. ParallelDofMapping primalDofMap; /// Mapping from dual DOF indices to a global index of duals. ParallelDofMapping dualDofMap; /// Stores to each dual DOF index the index of the first Lagrange /// constraint that is assigned to this DOF. ParallelDofMapping lagrangeMap; /// Index for each non primal DOF to the global index of B variables. ParallelDofMapping localDofMap; /// Mapping of pure local DOF indices, thus no primal and no dual DOFs are /// in this map. Is used for the Dirichlet preconditioner only. ParallelDofMapping interiorDofMap; /// Stores to each dual boundary DOF in each finite elment space the set of /// ranks in which the DOF is contained in. map boundaryDofRanks; /// Global PETSc matrix of Lagrange variables. Mat mat_lagrange; /// 0: Solve the Schur complement on primal variables with iterative solver. /// 1: Create the Schur complement matrix explicitly and solve it with a /// direct solver. int schurPrimalSolver; /// PETSc solver object to solve the Schur complement on the /// primal variables. KSP ksp_schur_primal; /// Matrix object that defines a matrix-free implementation for the action /// of the Schur complement on the primal variables. Mat mat_schur_primal; /// Data for MatMult operation in matrix \ref mat_schur_primal SchurPrimalData schurPrimalData; /// PETSc solver object to solve a system with FETI-DP. KSP ksp_feti; /// Matrix object that defines a matrix-free implementation for the action /// of the FETI-DP operator. Mat mat_feti; /// Data for MatMult operation in matrix \ref mat_feti FetiData fetiData; /// Defines which preconditioner should be used to solve the reduced /// FETI-DP system. FetiPreconditioner fetiPreconditioner; /// Preconditioner object for the reduced FETI-DP system. PC precon_feti; Mat mat_lagrange_scaled; FetiDirichletPreconData fetiDirichletPreconData; FetiLumpedPreconData fetiLumpedPreconData; Mat mat_interior_interior, mat_duals_duals, mat_interior_duals, mat_duals_interior; KSP ksp_interior; bool multiLevelTest; SubDomainSolver *subDomainSolver; }; } #endif