// ============================================================================ // == == // == 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 "parallel/PetscSolver.h" #include "parallel/ParallelTypes.h" #ifndef AMDIS_PETSC_SOLVER_FETI_H #define AMDIS_PETSC_SOLVER_FETI_H namespace AMDiS { using namespace std; #ifdef HAVE_PETSC_DEV /** \brief * This structure is used when defining the MatShell operation for solving * primal schur complement. \ref petscMultMatSchurPrimal */ struct PetscSchurPrimalData { /// Pointers to the matrix containing the primal variables. Mat *mat_primal_primal; /// Coupling matrices between the primal and the B variables. Mat *mat_primal_b, *mat_b_primal; /// Temporal vector on the B variables. Vec tmp_vec_b; /// Temporal vecor in the primal variables. Vec tmp_vec_primal; /// Pointer to the solver for \ref PetscSolverFeti::mat_bb. KSP *ksp_b; }; /** \brief * This structure is used when defining the FETI-DP operator for solving * the system matrix reduced to the Lagrange multipliers. * \ref petscMultMatFeti */ struct FetiData { /// Pointers to the matrix containing the primal variables. Mat *mat_primal_primal; /// Coupling matrices between the primal and the B variables. Mat *mat_primal_b, *mat_b_primal; /// Matrix of Lagrange variables. Mat *mat_lagrange; /// Temporal vector on the B variables. Vec tmp_vec_b; /// Temporal vector on the primal variables. Vec tmp_vec_primal; /// Temporal vector on the Lagrange variables. Vec tmp_vec_lagrange; /// Pointer to the solver for \ref PetscSolverFeti::mat_bb. KSP *ksp_b; /// Pointer to the solver of the schur complement on the primal variables. KSP *ksp_schur_primal; }; struct FetiDirichletPreconData { /// Matrix of scaled Lagrange variables. Mat *mat_lagrange_scaled; Mat *mat_interior_interior, *mat_duals_duals, *mat_interior_duals, *mat_duals_interior; /// Pointer to the solver for \ref PetscSolverFeti::mat_bb. KSP *ksp_interior; /// Temporal vector on the B variables. Vec tmp_vec_b; /// Temporal vector on the dual variables. Vec tmp_vec_duals0, tmp_vec_duals1; /// Temporal vector on the interior variables. Vec tmp_vec_interior; }; struct FetiLumpedPreconData { /// Matrix of scaled Lagrange variables. Mat *mat_lagrange_scaled; Mat *mat_duals_duals; /// Temporal vector on the B variables. Vec tmp_vec_b; /// Temporal vector on the dual variables. Vec tmp_vec_duals0, tmp_vec_duals1; }; typedef enum { FETI_NONE = 0, FETI_DIRICHLET = 1, FETI_LUMPED = 2 } FetiPreconditioner; /** \brief * FETI-DP implementation based on PETSc. */ class PetscSolverFeti : public PetscSolver { public: PetscSolverFeti(); /// Assemble the sequentially created matrices and vectors to the /// global matrices and vectors required by the FETI-DP method. void fillPetscMatrix(Matrix *mat, SystemVector *vec); /// Solve the system using FETI-DP method. void solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo); /// 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; } protected: /// After mesh changes, or if the solver is called the first time, this /// function creates all matrix and vector objects with the approriated /// sizes. void updateDofData(); /// Defines which boundary nodes are primal. Creates global index of /// the primal variables. void createPrimals(); /// Defines the set of dual variables and creates the global index of // dual variables. void createDuals(); /// Create Lagrange multiplier variables corresponding to the dual /// variables. void createLagrange(); /// Creates a global index of the B variables. void createIndexB(); /// Creates the Lagrange multiplier constraints and assembles them /// to \ref mat_lagrange. void createMatLagrange(); /// Creates PETSc KSP solver object for solving the Schur complement /// system on the primal variables, \ref ksp_schur_primal void createSchurPrimalKsp(); /// 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(); /// 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); protected: /// Number of components in the PDE to be solved. int nComponents; /// Set of DOF indices that are considered to be primal variables. DofIndexSet primals; /// Mapping from primal DOF indices to a global index of primals. DofMapping globalPrimalIndex; /// Number of rank owned primals and global primals int nRankPrimals, nOverallPrimals, rStartPrimals; /// Set of DOF indices that are considered to be dual variables. DofIndexSet duals; /// Mapping from dual DOF indices to a global index of duals. DofMapping globalDualIndex; /// Stores to each dual boundary DOF the set of ranks in which the DOF /// is contained in. DofIndexToPartitions boundaryDofRanks; /// Stores to each dual DOF index the index of the first Lagrange /// constraint that is assigned to this DOF. DofMapping dofFirstLagrange; /// Number of rank owned Lagrange variables, number of global /// Lagrange variables. int nRankLagrange, nOverallLagrange, rStartLagrange; /// Index for each non primal variables to the global index of /// B variables. DofMapping globalIndexB; /// Number of non primal, thus B, variables on rank and globally. int nRankB, nOverallB, rStartB; /// Global PETSc matrix of non primal variables. Mat mat_b_b; /// Global PETSc matrix of primal variables. Mat mat_primal_primal; /// Global PETSc matrices that connect the primal with the non /// primal variables. Mat mat_b_primal, mat_primal_b; /// Global PETSc matrix of Lagrange variables. Mat mat_lagrange; /// Right hand side PETSc vectors for primal and non primal variables. Vec f_b, f_primal; /// PETSc solver object that inverts the matrix of non primal /// variables, \ref mat_b_b KSP ksp_b; /// 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 PetscSchurPrimalData petscSchurPrimalData; /// 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; int nLocalInterior; // Number of local nodes that are duals. int nLocalDuals; }; #endif } #endif