From e778c689f9eb869a8ba6560853ac393987b93d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Gr=C3=BCninger?= <christoph.grueninger@iws.uni-stuttgart.de> Date: Wed, 23 Mar 2016 06:58:30 +0100 Subject: [PATCH] [cleanup] Remove old headers from linear They were deprecated in 2.9 --- dumux/linear/CMakeLists.txt | 12 - dumux/linear/borderindex.hh | 56 -- dumux/linear/boxlinearsolver.hh | 573 ----------------- dumux/linear/domesticoverlapfrombcrsmatrix.hh | 512 --------------- dumux/linear/elementborderlistfromgrid.hh | 141 ----- dumux/linear/foreignoverlapfrombcrsmatrix.hh | 483 -------------- dumux/linear/globalindices.hh | 351 ----------- dumux/linear/overlappingbcrsmatrix.hh | 589 ------------------ dumux/linear/overlappingblockvector.hh | 458 -------------- dumux/linear/overlappingoperator.hh | 76 --- dumux/linear/overlappingpreconditioner.hh | 121 ---- dumux/linear/overlappingscalarproduct.hh | 86 --- dumux/linear/vertexborderlistfromgrid.hh | 122 ---- 13 files changed, 3580 deletions(-) delete mode 100644 dumux/linear/borderindex.hh delete mode 100644 dumux/linear/boxlinearsolver.hh delete mode 100644 dumux/linear/domesticoverlapfrombcrsmatrix.hh delete mode 100644 dumux/linear/elementborderlistfromgrid.hh delete mode 100644 dumux/linear/foreignoverlapfrombcrsmatrix.hh delete mode 100644 dumux/linear/globalindices.hh delete mode 100644 dumux/linear/overlappingbcrsmatrix.hh delete mode 100644 dumux/linear/overlappingblockvector.hh delete mode 100644 dumux/linear/overlappingoperator.hh delete mode 100644 dumux/linear/overlappingpreconditioner.hh delete mode 100644 dumux/linear/overlappingscalarproduct.hh delete mode 100644 dumux/linear/vertexborderlistfromgrid.hh diff --git a/dumux/linear/CMakeLists.txt b/dumux/linear/CMakeLists.txt index 77dd5223d8..938ef18ced 100644 --- a/dumux/linear/CMakeLists.txt +++ b/dumux/linear/CMakeLists.txt @@ -4,21 +4,9 @@ install(FILES amgbackend.hh amgparallelhelpers.hh amgproperties.hh -borderindex.hh -boxlinearsolver.hh -domesticoverlapfrombcrsmatrix.hh -elementborderlistfromgrid.hh -foreignoverlapfrombcrsmatrix.hh -globalindices.hh impetbicgstabilu0solver.hh linearsolverproperties.hh -overlappingbcrsmatrix.hh -overlappingblockvector.hh -overlappingoperator.hh -overlappingpreconditioner.hh -overlappingscalarproduct.hh pardisobackend.hh seqsolverbackend.hh vectorexchange.hh -vertexborderlistfromgrid.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/linear) diff --git a/dumux/linear/borderindex.hh b/dumux/linear/borderindex.hh deleted file mode 100644 index 3e8e823dc0..0000000000 --- a/dumux/linear/borderindex.hh +++ /dev/null @@ -1,56 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief A single index intersecting with the process boundary. - */ -#ifndef DUMUX_BORDER_INDEX_HH -#define DUMUX_BORDER_INDEX_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -namespace Dumux { - -/*! - * \brief A single index intersecting with the process boundary. - */ -struct BorderIndex -{ - //! Index of the entity for the local process - int localIdx; - - //! Index of the entity for the peer process - int peerIdx; - - //! Rank of the peer process - int peerRank; - - //! Distance to the process border for the peer (in hops) - int borderDistance; - - //! True if and only if the entity which corrosponds to the index - //! is in the interior of more than one process (i.e. the entity - //! is completely on the border) - bool isShared; -}; - -} - -#endif diff --git a/dumux/linear/boxlinearsolver.hh b/dumux/linear/boxlinearsolver.hh deleted file mode 100644 index defc4cd390..0000000000 --- a/dumux/linear/boxlinearsolver.hh +++ /dev/null @@ -1,573 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief Provides a linear solver for the stabilized BiCG method with - * an ILU-0 preconditioner. - */ -#ifndef DUMUX_BOXLINEARSOLVER_HH -#define DUMUX_BOXLINEARSOLVER_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <dune/common/deprecated.hh> -#include <dune/istl/solvers.hh> -#include <dune/istl/preconditioners.hh> - -#include <dumux/implicit/properties.hh> -#include <dumux/linear/seqsolverbackend.hh> -#include <dumux/linear/linearsolverproperties.hh> -#include <dumux/linear/vertexborderlistfromgrid.hh> -#include <dumux/linear/overlappingbcrsmatrix.hh> -#include <dumux/linear/overlappingblockvector.hh> -#include <dumux/linear/overlappingpreconditioner.hh> -#include <dumux/linear/overlappingscalarproduct.hh> -#include <dumux/linear/overlappingoperator.hh> - -namespace Dumux -{ - -/*! - * \ingroup Linear - * \brief Provides a linear solver for the stabilized BiCG method with - * an ILU-0 preconditioner. - * - * This solver's intention is to be used in conjunction with the box - * method, so it assumes that the vertices are the only DOFs. - */ -template <class TypeTag> -class BoxLinearSolver -{ - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dumux::OverlappingScalarProduct<OverlappingVector, Overlap> OverlappingScalarProduct; - typedef Dumux::OverlappingOperator<OverlappingMatrix, OverlappingVector, OverlappingVector> OverlappingOperator; - -public: - BoxLinearSolver(const Problem &problem, int overlapSize) - : problem_(problem) - , overlapSize_(overlapSize) - {} - - ~BoxLinearSolver() - { cleanup_(); } - - /*! - * \brief Set the structure of the linear system of equations to be solved. - * - * This method allocates space an does the necessary - * communication before actually calling the solve() method. As - * long as the structure of the linear system does not change, the - * solve method can be called arbitrarily often. - */ - void setStructureMatrix(const Matrix &M) - { - cleanup_(); - prepare_(); - } - - /*! - * \brief Actually solve the linear system of equations. - * - * \return true if the residual reduction could be achieved, else false. - */ - template <class PrecBackend, class SolverBackend> - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - int verbosity = 0; - if (problem_.gridView().comm().rank() == 0) - verbosity = GET_PARAM_FROM_GROUP(TypeTag, int, LinearSolver, Verbosity); - const int maxIter = GET_PARAM_FROM_GROUP(TypeTag, double, LinearSolver, MaxIterations); - const double residReduction = GET_PARAM_FROM_GROUP(TypeTag, double, LinearSolver, ResidualReduction); - - if (!overlapMatrix_) { - // make sure that the overlapping matrix and block vectors - // have been created - prepare_(M); - } - - // copy the values of the non-overlapping linear system of - // equations to the overlapping one. On ther border, we add up - // the values of all processes (using the assignAdd() methods) - overlapMatrix_->assignAdd(M); - overlapb_->assignAdd(b); - (*overlapx_) = 0.0; - - // create sequential and overlapping preconditioners - PrecBackend seqPreCond(*overlapMatrix_); - typedef typename PrecBackend::Implementation SeqPreconditioner; - typedef Dumux::OverlappingPreconditioner<SeqPreconditioner, Overlap> OverlappingPreconditioner; - OverlappingPreconditioner preCond(seqPreCond.imp(), overlapMatrix_->overlap()); - - // create the scalar products and linear operators for ISTL - OverlappingScalarProduct scalarProd(overlapMatrix_->overlap()); - OverlappingOperator opA(*overlapMatrix_); - - // create the actual solver - SolverBackend solver(opA, - scalarProd, - preCond, - residReduction, - maxIter, - verbosity); - - // run the solver - Dune::InverseOperatorResult result; - solver.imp().apply(*overlapx_, *overlapb_, result); - - // copy the result back to the non-overlapping vector - overlapx_->assignTo(x); - - // return the result of the solver - return result.converged; - } - -private: - void prepare_(const Matrix &M) - { - VertexBorderListFromGrid<GridView, VertexMapper> - borderListCreator(problem_.gridView(), problem_.vertexMapper()); - - // create the overlapping Jacobian matrix - overlapMatrix_ = std::make_shared<OverlappingMatrix> (M, - borderListCreator.foreignBorderList(), - borderListCreator.domesticBorderList(), - overlapSize_); - - // create the overlapping vectors for the residual and the - // solution - overlapb_ = std::make_shared<OverlappingVector>(overlapMatrix_->overlap()); - overlapx_ = std::make_shared<OverlappingVector>(*overlapb_); - } - - void cleanup_() - { - overlapMatrix_.template reset<OverlappingMatrix>(0); - overlapb_.template reset<OverlappingVector>(0); - overlapx_.template reset<OverlappingVector>(0); - } - - const Problem &problem_; - - int overlapSize_; - std::shared_ptr<OverlappingMatrix> overlapMatrix_; - std::shared_ptr<OverlappingVector> overlapb_; - std::shared_ptr<OverlappingVector> overlapx_; -}; - -template <class TypeTag, class Imp> -class PrecNoIterBackend -{ -public: - typedef Imp Implementation; - - template <class Matrix> - PrecNoIterBackend(Matrix& A) - : imp_(A, GET_PARAM_FROM_GROUP(TypeTag, double, LinearSolver, PreconditionerRelaxation)) - {} - - Imp& imp() - { - return imp_; - } - -private: - Imp imp_; -}; - -template <class TypeTag, class Imp> -class PrecIterBackend -{ -public: - typedef Imp Implementation; - - template <class Matrix> - PrecIterBackend(Matrix& A) - : imp_(A, - GET_PARAM_FROM_GROUP(TypeTag, int, LinearSolver, PreconditionerIterations), - GET_PARAM_FROM_GROUP(TypeTag, double, LinearSolver, PreconditionerRelaxation)) - {} - - Imp& imp() - { - return imp_; - } - -private: - Imp imp_; -}; - -/*! - * \brief A standard solver backend. - */ -template <class TypeTag, class Imp> -class StandardSolverBackend -{ -public: - typedef Imp Implementation; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - - template <class Operator, class ScalarProduct, class Prec> - StandardSolverBackend(Operator& A, ScalarProduct& sp, Prec& prec, - Scalar residReduction, int maxIter, int verbosity) - : imp_(A, sp, prec, residReduction, maxIter, verbosity) - {} - - Imp& imp() - { - return imp_; - } - -private: - Imp imp_; -}; - -/*! - * \brief Backend for an ILU0-preconditioned BiCGSTAB solver. - */ -template <class TypeTag> -class BoxBiCGStabILU0Solver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqILU0<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecNoIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::BiCGSTABSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use ILU0BiCGSTABBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxBiCGStabILU0Solver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for an SOR-preconditioned BiCGSTAB solver. - */ -template <class TypeTag> -class BoxBiCGStabSORSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqSOR<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::BiCGSTABSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use SORBiCGSTABBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxBiCGStabSORSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for an SSOR-preconditioned BiCGSTAB solver. - */ -template <class TypeTag> -class BoxBiCGStabSSORSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqSSOR<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::BiCGSTABSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use SSORBiCGSTABBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxBiCGStabSSORSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for a Jacobi-preconditioned BiCGSTAB solver. - */ -template <class TypeTag> -class BoxBiCGStabJacSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqJac<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::BiCGSTABSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use JacBiCGSTABBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxBiCGStabJacSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for a Gauss-Seidel-preconditioned BiCGSTAB solver. - */ -template <class TypeTag> -class BoxBiCGStabGSSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqGS<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::BiCGSTABSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use GSBiCGSTABBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxBiCGStabGSSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for an ILU0-preconditioned CG solver. - */ -template <class TypeTag> -class BoxCGILU0Solver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqILU0<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecNoIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::CGSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use ILUnCGBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxCGILU0Solver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for an SOR-preconditioned CG solver. - */ -template <class TypeTag> -class BoxCGSORSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqSOR<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::CGSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use SORCGBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxCGSORSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for an SSOR-preconditioned CG solver. - */ -template <class TypeTag> -class BoxCGSSORSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqSSOR<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::CGSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use SSORCGBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxCGSSORSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for a Jacobi-preconditioned CG solver. - */ -template <class TypeTag> -class BoxCGJacSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqJac<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::CGSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use JacCGBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxCGJacSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -/*! - * \brief Backend for a Gauss-Seidel-preconditioned CG solver. - */ -template <class TypeTag> -class BoxCGGSSolver : public BoxLinearSolver<TypeTag> -{ - typedef BoxLinearSolver<TypeTag> ParentType; - typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) Matrix; - typedef Dumux::OverlappingBCRSMatrix<Matrix> OverlappingMatrix; - typedef typename OverlappingMatrix::Overlap Overlap; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) Vector; - typedef Dumux::OverlappingBlockVector<typename Vector::block_type, Overlap> OverlappingVector; - typedef Dune::SeqGS<OverlappingMatrix, OverlappingVector, OverlappingVector> SeqPreconditioner; - typedef PrecIterBackend<TypeTag, SeqPreconditioner> PrecBackend; - typedef Dune::CGSolver<OverlappingVector> Solver; - typedef StandardSolverBackend<TypeTag, Solver> SolverBackend; - -public: - template <class Problem> - DUNE_DEPRECATED_MSG("Use GSCGBackend/AMGBackend from seqsolverbackend.hh/amgbackend.hh instead") - BoxCGGSSolver(const Problem &problem, int overlapSize = 1) - : ParentType(problem, overlapSize) - {} - - bool solve(const Matrix &M, - Vector &x, - const Vector &b) - { - return ParentType::template solve<PrecBackend, SolverBackend>(M, x, b); - } -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/domesticoverlapfrombcrsmatrix.hh b/dumux/linear/domesticoverlapfrombcrsmatrix.hh deleted file mode 100644 index cbef540978..0000000000 --- a/dumux/linear/domesticoverlapfrombcrsmatrix.hh +++ /dev/null @@ -1,512 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief This class creates and manages the foreign overlap given an - * initial list of border indices and a BCRS matrix. - * - * The foreign overlap are all (row) indices which overlap with the - * some of the current process's local indices. - */ -#ifndef DUMUX_DOMESTIC_OVERLAP_FROM_BCRS_MATRIX_HH -#define DUMUX_DOMESTIC_OVERLAP_FROM_BCRS_MATRIX_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <list> -#include <set> -#include <map> -#include <memory> -#include <tuple> - -#include <dumux/parallel/mpibuffer.hh> - -#include "foreignoverlapfrombcrsmatrix.hh" -#include "globalindices.hh" - -namespace Dumux { - -/*! - * \brief This class creates and manages the foreign overlap given an - * initial list of border indices and a BCRS matrix. - * - * The foreign overlap are all (row) indices which overlap with the - * some of the current process's local indices. - */ -template<class BCRSMatrix> -class DomesticOverlapFromBCRSMatrix -{ - DomesticOverlapFromBCRSMatrix(const DomesticOverlapFromBCRSMatrix &A) - {} - - typedef Dumux::ForeignOverlapFromBCRSMatrix<BCRSMatrix> ForeignOverlap; - typedef Dumux::GlobalIndices<ForeignOverlap> GlobalIndices; - -public: - typedef int ProcessRank; - typedef int BorderDistance; - typedef int Index; - typedef Index LocalIndex; - typedef std::tuple<Index, BorderDistance, int> IndexDistanceNpeers; - - typedef std::set<ProcessRank> PeerSet; - - typedef std::list<IndexDistanceNpeers> ForeignOverlapWithPeer; - - typedef std::pair<LocalIndex, BorderDistance> IndexDistance; - typedef std::set<LocalIndex> DomesticOverlapWithPeer; - typedef std::map<ProcessRank, DomesticOverlapWithPeer> DomesticOverlapByRank; - typedef std::vector<std::map<ProcessRank, BorderDistance> > DomesticOverlapByIndex; - - typedef std::list<BorderIndex> BorderList; - - /*! - * \brief Constructs the foreign overlap given a BCRS matrix and - * an initial list of border indices. - */ - DomesticOverlapFromBCRSMatrix(const BCRSMatrix &A, - const BorderList &borderList, - const BorderList &domesticBorderList, - int overlapSize) - : foreignOverlap_(A, borderList, domesticBorderList, overlapSize) - , globalIndices_(foreignOverlap_) - { - myRank_ = 0; - -#if HAVE_MPI - MPI_Comm_rank(MPI_COMM_WORLD, &myRank_); -#endif // HAVE_MPI - - buildDomesticOverlap_(A); - } - - /*! - * \brief Return the border list. - * - * The border list is the list of (local index, peer index, peer - * rank) triples for all indices on a process border. - */ - const BorderList& borderList() const - { return foreignOverlap_.borderList(); } - - - /*! - * \brief Returns true iff a domestic index is a border index. - */ - bool isBorder(int domesticIdx) const - { - return isLocal(domesticIdx) && foreignOverlap_.isBorder(domesticIdx); - } - - /*! - * \brief Returns true iff a domestic index is a front index. - */ - bool isFront(int domesticIdx) const - { return borderDistance_[domesticIdx] == foreignOverlap_.overlapSize(); } - - /*! - * \brief Returns the number of processes which "see" a given - * index. - */ - int numPeers(int domesticIdx) const - { return domesticOverlapByIndex_[domesticIdx].size(); } - - /*! - * \brief Returns whether a given domestic index is a front index - * for a given peer process. - */ - int isFrontFor(int peerRank, int domesticIdx) const - { - typedef std::map<ProcessRank, BorderDistance>::const_iterator iterator; - iterator it = domesticOverlapByIndex_[domesticIdx].find(peerRank); - if (it == domesticOverlapByIndex_[domesticIdx].end()) - return false; // not seen by the process - - return it->second == foreignOverlap_.overlapSize(); - } - - /*! - * \brief Return the number of processes which "see" a domestic - * index and for which the index is not on the front. - */ - int numNonFrontProcesses(int domesticIdx) const - { - int result = 0; - if (!isFront(domesticIdx)) - ++result; - - typedef std::map<ProcessRank, BorderDistance>::const_iterator iterator; - iterator it = domesticOverlapByIndex_[domesticIdx].begin(); - iterator endIt = domesticOverlapByIndex_[domesticIdx].end(); - for (; it != endIt; ++it) { - if (it->second < overlapSize()) - ++result; - } - - return result; - } - - /*! - * \brief Returns the rank of the current process. - */ - int myRank() const - { return myRank_; } - - /*! - * \brief Return the set of process ranks which share an overlap - * with the current process. - */ - const PeerSet &peerSet() const - { return peerSet_; } - - - /*! - * \brief Returns the foreign overlap - */ - const ForeignOverlap &foreignOverlap() const - { return foreignOverlap_; } - - /*! - * \brief Returns the size of the overlap region - */ - int overlapSize() const - { return foreignOverlap_.overlapSize(); } - - /*! - * \brief Returns the foreign overlap of a peer process - */ - const ForeignOverlapWithPeer &foreignOverlapWithPeer(ProcessRank peerRank) const - { return foreignOverlap_.foreignOverlapWithPeer(peerRank); } - - /*! - * \brief Returns the domestic overlap with a peer process - */ - const DomesticOverlapWithPeer &domesticOverlapWithPeer(ProcessRank peerRank) const - { - assert(domesticOverlapWithPeer_.find(peerRank) != domesticOverlapWithPeer_.end()); - return domesticOverlapWithPeer_.find(peerRank)->second; - } - - /*! - * \brief Returns true iff a given local index is a remote index for a given peer - */ - bool isRemoteIndexFor(ProcessRank peerRank, Index localIdx) const - { return foreignOverlap_.isRemoteIndexFor(peerRank, localIdx); } - - /*! - * \brief Returns true iff a given local index is also a local index for a given peer - */ - bool isLocalIndexFor(ProcessRank peerRank, Index domesticIdx) const - { return foreignOverlap_.isLocalIndexFor(peerRank, domesticIdx); } - - /*! - * \brief Returns true iff a given local index is a domestic index for a given peer - */ - bool isDomesticIndexFor(ProcessRank peerRank, Index domesticIdx) const - { return foreignOverlap_.isDomesticIndexFor(peerRank, domesticIdx); } - - /*! - * \brief Returns the number local indices - */ - int numLocal() const - { return foreignOverlap_.numLocal(); } - - /*! - * \brief Returns the number domestic indices. - * - * The domestic indices are defined as the process' local indices - * plus its copies of indices in the overlap regions - */ - int numDomestic() const - { return globalIndices_.numDomestic(); } - - /*! - * \brief Return true if a domestic index is local for the process - * (i.e. interior or border) - */ - bool isLocal(int domesticIdx) const - { return domesticIdx < numLocal(); } - - /*! - * \brief Return true iff the current process is the master of a - * given domestic index. - */ - bool iAmMasterOf(int domesticIdx) const - { - if (!isLocal(domesticIdx)) - return false; - return foreignOverlap_.masterOf(domesticIdx) == myRank_; - } - - /*! - * \brief Return true iff a given index is shared by more than one process - */ - bool isShared(int domesticIdx) const - { - if (!isLocal(domesticIdx)) - return false; - return foreignOverlap_.isShared(domesticIdx); - } - - /*! - * \brief Return true iff a given rank is the master of a given - * domestic index. - */ - bool isMasterOf(int peerRank, int domesticIdx) const - { - if (isLocal(domesticIdx)) { - return foreignOverlap_.masterOf(domesticIdx) == peerRank; - } - - // if the local index is a border index, loop over all ranks - // for which this index is also a border index. the lowest - // rank wins! - typedef typename std::map<ProcessRank, BorderDistance>::const_iterator iterator; - iterator it = domesticOverlapByIndex_[domesticIdx].begin(); - iterator endIt = domesticOverlapByIndex_[domesticIdx].end(); - LocalIndex masterIdx = std::numeric_limits<int>::max(); - for (; it != endIt; ++it) { - masterIdx = std::min(masterIdx, it->first); - } - - return masterIdx == peerRank; - } - - /*! - * \brief Print the foreign overlap for debugging purposes. - */ - void print() const - { - globalIndices_.print(); - } - - /*! - * \brief Returns a domestic index given a global one - */ - Index globalToDomestic(Index globalIdx) const - { - return globalIndices_.globalToDomestic(globalIdx); - } - - /*! - * \brief Returns a global index given a domestic one - */ - Index domesticToGlobal(Index domIdx) const - { - return globalIndices_.domesticToGlobal(domIdx); - } - -protected: - void buildDomesticOverlap_(const BCRSMatrix &A) - { - // copy the set of peers from the foreign overlap - peerSet_ = foreignOverlap_.peerSet(); - - // resize the array which stores the number of peers for - // each entry. - domesticOverlapByIndex_.resize(numLocal()); - borderDistance_.resize(numLocal(), -1); - - // for all local indices copy the number of processes from the - // foreign overlap - for (int localIdx = 0; localIdx < numLocal(); ++localIdx) { - const std::map<ProcessRank, BorderDistance> &idxOverlap = - foreignOverlap_.foreignOverlapByIndex(localIdx); - std::map<ProcessRank, BorderDistance>::const_iterator it = idxOverlap.begin(); - std::map<ProcessRank, BorderDistance>::const_iterator endIt = idxOverlap.end(); - for (; it != endIt; ++it) { - int peerRank = it->first; - int borderDist = it->second; - domesticOverlapByIndex_[localIdx][peerRank] = borderDist; - domesticOverlapWithPeer_[peerRank].insert(localIdx); - } - } - - PeerSet::const_iterator peerIt; - PeerSet::const_iterator peerEndIt = foreignOverlap_.peerSet().end(); - - // send the overlap indices to all peer processes - peerIt = foreignOverlap_.peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - sendIndicesToPeer_(peerRank); - } - - // receive our overlap from the processes to all peer processes - peerIt = foreignOverlap_.peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - receiveIndicesFromPeer_(peerRank); - } - - // receive our overlap from the processes to all peer processes - peerIt = foreignOverlap_.peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - waitSendIndices_(peerRank); - } - } - - void sendIndicesToPeer_(int peerRank) - { -#if HAVE_MPI - const ForeignOverlapWithPeer &foreignOverlap - = foreignOverlap_.foreignOverlapWithPeer(peerRank); - - // first, send a message containing the number of additional - // indices stemming from the overlap (i.e. without the border - // indices) - int numIndices = foreignOverlap.size(); - numIndicesSendBuff_[peerRank] = std::make_shared<MpiBuffer<int> >(1); - (*numIndicesSendBuff_[peerRank])[0] = numIndices; - numIndicesSendBuff_[peerRank]->send(peerRank); - - // create MPI buffers - indicesSendBuff_[peerRank] = std::make_shared<MpiBuffer<IndexDistanceNpeers> >(numIndices); - - // then send the additional indices themselfs - ForeignOverlapWithPeer::const_iterator overlapIt = foreignOverlap.begin(); - ForeignOverlapWithPeer::const_iterator overlapEndIt = foreignOverlap.end(); - for (int i = 0; overlapIt != overlapEndIt; ++overlapIt, ++i) { - int localIdx = std::get<0>(*overlapIt); - int borderDistance = std::get<1>(*overlapIt); - - const std::map<ProcessRank, BorderDistance> &foreignIndexOverlap - = foreignOverlap_.foreignOverlapByIndex(localIdx); - - int numPeers = foreignIndexOverlap.size(); - - (*indicesSendBuff_[peerRank])[i] = - IndexDistanceNpeers(globalIndices_.domesticToGlobal(localIdx), - borderDistance, - numPeers); - - // send all peer ranks which see the given index - peersSendBuff_[peerRank].push_back(std::make_shared<MpiBuffer<int> >(2*numPeers)); - typename std::map<ProcessRank, BorderDistance>::const_iterator it = foreignIndexOverlap.begin(); - typename std::map<ProcessRank, BorderDistance>::const_iterator endIt = foreignIndexOverlap.end(); - for (int j = 0; it != endIt; ++it, ++j) - { - (*peersSendBuff_[peerRank][i])[2*j + 0] = it->first; - (*peersSendBuff_[peerRank][i])[2*j + 1] = it->second; - } - } - - // send all messages - indicesSendBuff_[peerRank]->send(peerRank); - overlapIt = foreignOverlap.begin(); - for (int i = 0; overlapIt != overlapEndIt; ++overlapIt, ++i) { - peersSendBuff_[peerRank][i]->send(peerRank); - } -#endif // HAVE_MPI - } - - void waitSendIndices_(int peerRank) - { - numIndicesSendBuff_[peerRank]->wait(); - numIndicesSendBuff_[peerRank].template reset<MpiBuffer<int> >(0); - - indicesSendBuff_[peerRank]->wait(); - indicesSendBuff_[peerRank].template reset<MpiBuffer<IndexDistanceNpeers> >(0); - - const ForeignOverlapWithPeer &foreignPeerOverlap - = foreignOverlap_.foreignOverlapWithPeer(peerRank); - ForeignOverlapWithPeer::const_iterator overlapIt = foreignPeerOverlap.begin(); - ForeignOverlapWithPeer::const_iterator overlapEndIt = foreignPeerOverlap.end(); - for (int i = 0; overlapIt != overlapEndIt; ++overlapIt, ++i) { - peersSendBuff_[peerRank][i]->wait(); - peersSendBuff_[peerRank][i].template reset<MpiBuffer<int> >(0); - } - } - - void receiveIndicesFromPeer_(int peerRank) - { -#if HAVE_MPI - // receive the number of additional indices - int numIndices = -1; - MpiBuffer<int> numIndicesRecvBuff(1); - numIndicesRecvBuff.receive(peerRank); - numIndices = numIndicesRecvBuff[0]; - - // receive the additional indices themselfs - MpiBuffer<IndexDistanceNpeers> recvBuff(numIndices); - recvBuff.receive(peerRank); - for (int i = 0; i < numIndices; ++i) { - int globalIdx = std::get<0>(recvBuff[i]); - int borderDistance = std::get<1>(recvBuff[i]); - int numPeers = std::get<2>(recvBuff[i]); - - int domesticIdx; - if (borderDistance > 0) { - // if the index is not on the border, add it to the - // domestic overlap - if (!globalIndices_.hasGlobalIndex(globalIdx)) { - // create and add a new domestic index - domesticIdx = globalIndices_.numDomestic(); - borderDistance_.resize(domesticIdx + 1, std::numeric_limits<int>::max()); - domesticOverlapByIndex_.resize(domesticIdx + 1); - - globalIndices_.addIndex(domesticIdx, globalIdx); - domesticOverlapByIndex_[domesticIdx][peerRank] = borderDistance; - domesticOverlapWithPeer_[peerRank].insert(domesticIdx); - } - else { - domesticIdx = globalIndices_.globalToDomestic(globalIdx); - } - } - else - // border index - domesticIdx = globalIndices_.globalToDomestic(globalIdx); - - borderDistance_[domesticIdx] = std::min(borderDistance, borderDistance_[domesticIdx]); - - // receive the peer ranks which see this index - MpiBuffer<ProcessRank> peerRanksRecvBuff(2*numPeers); - peerRanksRecvBuff.receive(peerRank); - for (int j = 0; j < numPeers; ++j) { - int seenBy = peerRanksRecvBuff[2*j + 0]; - int borderDistance2 = peerRanksRecvBuff[2*j + 1]; - if (seenBy != myRank_) { - domesticOverlapByIndex_[domesticIdx][seenBy] = borderDistance2; - domesticOverlapWithPeer_[seenBy].insert(domesticIdx); - peerSet_.insert(seenBy); - } - } - } -#endif // HAVE_MPI - } - - int myRank_; - ForeignOverlap foreignOverlap_; - - DomesticOverlapByRank domesticOverlapWithPeer_; - DomesticOverlapByIndex domesticOverlapByIndex_; - std::vector<int> borderDistance_; - - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > numIndicesSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<IndexDistanceNpeers> > > indicesSendBuff_; - std::map<ProcessRank, std::vector<std::shared_ptr<MpiBuffer<int> > > > peersSendBuff_; - GlobalIndices globalIndices_; - PeerSet peerSet_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/elementborderlistfromgrid.hh b/dumux/linear/elementborderlistfromgrid.hh deleted file mode 100644 index 9d644c2158..0000000000 --- a/dumux/linear/elementborderlistfromgrid.hh +++ /dev/null @@ -1,141 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief Creates a list of element indices on the process border which - * can be used to construct the foreign overlap. - */ -#ifndef DUMUX_ELEMENT_BORDER_LIST_FROM_GRID_HH -#define DUMUX_ELEMENT_BORDER_LIST_FROM_GRID_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <dune/grid/common/datahandleif.hh> -#include <dune/grid/common/gridenums.hh> -#include <dune/common/fmatrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/scalarproducts.hh> -#include <dune/istl/operators.hh> - -#include "borderindex.hh" - -#include <algorithm> -#include <list> -#include <set> -#include <map> - -namespace Dumux { - - -/*! - * \brief Uses communication on the grid to find the initial seed list - * of indices. - * - * \todo implement this class generically. For this, it must be - * possible to query the mapper whether it contains entities of - * a given codimension without the need to hand it an actual - * entity. - */ -template <class GridView, class ElementMapper> -class ElementBorderListFromGrid : public Dune::CommDataHandleIF<ElementBorderListFromGrid<GridView, ElementMapper>, - int > -{ - typedef std::list<BorderIndex> BorderList; - -public: - ElementBorderListFromGrid(const GridView &gridView, - const ElementMapper &map) - : gridView_(gridView), map_(map) - { - forwardComm_ = true; - gridView.communicate(*this, - Dune::InteriorBorder_All_Interface, - Dune::ForwardCommunication); - - forwardComm_ = false; - gridView.communicate(*this, - Dune::InteriorBorder_All_Interface, - Dune::BackwardCommunication); - } - - // data handle methods - bool contains (int dim, int codim) const - { return codim == 0; } - - bool fixedsize(int dim, int codim) const - { return true; } - - template<class EntityType> - size_t size(const EntityType &e) const - { return 2; } - - template<class MessageBufferImp, class EntityType> - void gather(MessageBufferImp &buff, const EntityType &e) const - { - buff.write(gridView_.comm().rank()); - buff.write(map_.index(e)); - } - - template<class MessageBufferImp, class EntityType> - void scatter(MessageBufferImp &buff, const EntityType &e, size_t n) - { - BorderIndex bIdx; - - bIdx.localIdx = map_.index(e); - buff.read(bIdx.peerRank); - buff.read(bIdx.peerIdx); - bIdx.borderDistance = 0; - // this index is not shared between at least two processes - // because an element is always in the interior of exactly one - // process - bIdx.isShared = false; - - if (forwardComm_) { - // add the index to the list of indices which we intersect - // with remote processes. - domesticBorderList_.push_back(bIdx); - } - else { - // add the index to the list of remote processes - // intersecting with us. - foreignBorderList_.push_back(bIdx); - } - } - - // Access to the initial border list. - const BorderList &foreignBorderList() const - { return foreignBorderList_; } - - // Access to the indices which are on the border but which are in - // the interior of a remote process - const BorderList &domesticBorderList() const - { return domesticBorderList_; } - -private: - const GridView gridView_; - const ElementMapper &map_; - bool forwardComm_; - BorderList foreignBorderList_; - BorderList domesticBorderList_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/foreignoverlapfrombcrsmatrix.hh b/dumux/linear/foreignoverlapfrombcrsmatrix.hh deleted file mode 100644 index 9bdf7e29f1..0000000000 --- a/dumux/linear/foreignoverlapfrombcrsmatrix.hh +++ /dev/null @@ -1,483 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief This class creates and manages the foreign overlap given an - * initial list of border indices and a BCRS matrix. - * - * The foreign overlap are all (row) indices which overlap with the - * some of the current process's local indices. - */ -#ifndef DUMUX_FOREIGN_OVERLAP_FROM_BCRS_MATRIX_HH -#define DUMUX_FOREIGN_OVERLAP_FROM_BCRS_MATRIX_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <list> -#include <set> -#include <map> -#include <tuple> - -#if HAVE_MPI -#include <mpi.h> -#endif // HAVE_MPI - -#include <dune/common/fmatrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/scalarproducts.hh> -#include <dune/istl/operators.hh> - -#include "borderindex.hh" - -namespace Dumux { - -/*! - * \brief This class creates and manages the foreign overlap given an - * initial list of border indices and a BCRS matrix. - * - * The foreign overlap are all (row) indices which overlap with the - * some of the current process's local indices. - */ -template<class BCRSMatrix> -class ForeignOverlapFromBCRSMatrix -{ - ForeignOverlapFromBCRSMatrix(const ForeignOverlapFromBCRSMatrix &A) - {} - -public: - typedef int ProcessRank; - typedef int BorderDistance; - typedef int Index; - typedef Index LocalIndex; - typedef std::pair<LocalIndex, ProcessRank> IndexRank; - typedef std::tuple<LocalIndex, ProcessRank, BorderDistance> IndexRankDist; - typedef std::tuple<Index, BorderDistance, int> IndexDistanceNpeers; - typedef std::list<IndexRankDist> SeedList; - - typedef std::set<ProcessRank> PeerSet; - typedef std::list<IndexDistanceNpeers> ForeignOverlapWithPeer; - typedef std::map<ProcessRank, ForeignOverlapWithPeer> ForeignOverlapByRank; - typedef std::vector<std::map<ProcessRank, BorderDistance> > ForeignOverlapByIndex; - - typedef std::list<BorderIndex> BorderList; - - /*! - * \brief Constructs the foreign overlap given a BCRS matrix and - * an initial list of border indices. - */ - ForeignOverlapFromBCRSMatrix(const BCRSMatrix &A, - const BorderList &foreignBorderList, - const BorderList &domesticBorderList, - int overlapSize) - : foreignBorderList_(foreignBorderList) - , domesticBorderList_(domesticBorderList) - { - overlapSize_ = overlapSize; - - myRank_ = 0; -#if HAVE_MPI - MPI_Comm_rank(MPI_COMM_WORLD, &myRank_); -#endif - - numLocal_ = A.N(); - - // calculate the border list. From this, create an initial - // seed list of indices which are in the overlap. - SeedList initialSeedList; - borderListToSeedList_(initialSeedList, foreignBorderList); - - // find the set of processes which have an overlap with the - // local processes. (i.e. the set of processes which we will - // have to communicate to.) - seedListToPeerSet_(initialSeedList); - - // calculate the foreign overlap for the local partition, - // i.e. find the distance of each row from the seed set. - foreignOverlapByIndex_.resize(A.N()); - extendForeignOverlap_(A, initialSeedList, overlapSize); - - updateMasterRanks_(foreignBorderList, domesticBorderList); - - // group foreign overlap by peer process rank - groupForeignOverlapByRank_(); - } - - /*! - * \brief Returns true iff a local index is a border index. - */ - bool isBorder(int localIdx) const - { return borderIndices_.count(localIdx) > 0; } - - /*! - * \brief Return the rank of the master process for a local index. - */ - int masterOf(int localIdx) const - { return masterRank_[localIdx]; } - - /*! - * \brief Return true if the current rank is the "master" of an - * index. - * - * We define the master process as the process with the lowest - * rank where the index is local. For a process is always the - * master of its interior indices, but for border indices it is - * only master if the index is not shared with a process of lower - * rank. - */ - bool iAmMasterOf(int localIdx) const - { return masterRank_[localIdx] == myRank_; } - - /*! - * \brief Returns the list of indices which intersect the process - * border and are in the interior of the local process. - */ - const BorderList &foreignBorderList() const - { return foreignBorderList_; } - - /*! - * \brief Returns the list of indices which intersect the process - * border and are in the interior of some remote process. - */ - const BorderList &domesticBorderList() const - { return domesticBorderList_; } - - /*! - * \brief Return true if a given local index is a domestic index - * for a peer. - */ - bool isDomesticIndexFor(ProcessRank peerRank, Index localIdx) const - { - if (!isLocal(localIdx)) - // our own remote indices do not count! - return false; - - typedef std::map<ProcessRank, BorderDistance> BorderDistMap; - const BorderDistMap &borderDist = foreignOverlapByIndex_[localIdx]; - BorderDistMap::const_iterator bdIt = borderDist.find(peerRank); - if (bdIt == borderDist.end()) - return false; // this index is not seen by the peer - - // the index is seen by the peer - return true; - } - - /*! - * \brief Return the list of (local indices, border distance, - * number of processes) triples which are in the overlap of - * a given peer rank. - */ - const ForeignOverlapWithPeer &foreignOverlapWithPeer(int peerRank) const - { - assert(foreignOverlapByRank_.find(peerRank) != foreignOverlapByRank_.end()); - return foreignOverlapByRank_.find(peerRank)->second; - } - - /*! - * \brief Return the map of (peer rank, border distance) for a given local index. - */ - const std::map<ProcessRank, BorderDistance> &foreignOverlapByIndex(int localIdx) const - { - assert(isLocal(localIdx)); - return foreignOverlapByIndex_[localIdx]; - } - - /*! - * \brief Return the set of process ranks which share an overlap - * with the current process. - */ - const PeerSet &peerSet() const - { return peerSet_; } - - /*! - * \brief Returns the number local indices - */ - int numLocal() const - { return numLocal_; } - - /*! - * \brief Returns true iff a domestic index is local - */ - bool isLocal(int domesticIdx) const - { - return domesticIdx < numLocal(); - } - - /*! - * \brief Returns true iff a local index is shared with an other process. - */ - bool isShared(int domesticIdx) const - { return isLocal(domesticIdx) && isShared_[domesticIdx]; } - - /*! - * \brief Return the number of peer ranks for which a given local - * index is visible. - */ - int numPeers(int localIdx) const - { return foreignOverlapByIndex_[localIdx].size(); } - - /*! - * \brief Returns the size of the overlap region - */ - int overlapSize() const - { return overlapSize_; } - - /*! - * \brief Print the foreign overlap for debugging purposes. - */ - void print() const - { - ForeignOverlapByRank::const_iterator it = foreignOverlapByRank_.begin(); - ForeignOverlapByRank::const_iterator endIt = foreignOverlapByRank_.end(); - for (; it != endIt; ++it) { - std::cout << "Overlap rows(distance) for rank " << it->first << ": "; - - ForeignOverlapWithPeer::const_iterator rowIt = it->second.begin(); - ForeignOverlapWithPeer::const_iterator rowEndIt = it->second.end(); - for (; rowIt != rowEndIt; ++rowIt) { - std::cout << std::get<0>(*rowIt) << "(" << std::get<1>(*rowIt) << ") "; - } - std::cout << "\n"; - } - } - -protected: - // Calculate the set of peer processes from the initial seed list. - void seedListToPeerSet_(const SeedList &seedList) - { - SeedList::const_iterator it = seedList.begin(); - SeedList::const_iterator endIt = seedList.end(); - for (; it != endIt; ++it) - peerSet_.insert(std::get<1>(*it)); - } - - // calculate the local border indices given the initial seed list - void borderListToSeedList_(SeedList &initialSeedList, const BorderList &borderList) - { - BorderList::const_iterator it = borderList.begin(); - BorderList::const_iterator endIt = borderList.end(); - for (; it != endIt; ++it) { - initialSeedList.push_back(IndexRankDist(it->localIdx, - it->peerRank, - it->borderDistance)); - borderIndices_.insert(it->localIdx); - } - } - - // given a list of border indices and provided that - // borderListToSeedList_() was already called, calculate the - // master process of each local index. - void updateMasterRanks_(const BorderList &foreignBorderList, - const BorderList &domesticBorderList) - { - // determine the minimum rank for all indices - masterRank_.resize(numLocal_, myRank_); - for (unsigned int localIdx = 0; localIdx < masterRank_.size(); ++localIdx) { - int masterRank = myRank_; - if (isBorder(localIdx)) { - // if the local index is a border index, loop over all ranks - // for which this index is also a border index. the lowest - // rank wins! - typedef typename std::map<ProcessRank, BorderDistance>::const_iterator iterator; - iterator it = foreignOverlapByIndex_[localIdx].begin(); - iterator endIt = foreignOverlapByIndex_[localIdx].end(); - for (; it != endIt; ++it) { - if (it->second == 0) { - // if the border distance is zero, the rank with the minimum - masterRank = std::min(masterRank, it->first); - } - } - } - masterRank_[localIdx] = masterRank; - } - - // overwrite the master rank of the non-shared border indices - isShared_.resize(numLocal_, false); - BorderList::const_iterator it = foreignBorderList.begin(); - BorderList::const_iterator endIt = foreignBorderList.end(); - for (; it != endIt; ++it) { - if (!it->isShared) - masterRank_[it->localIdx] = myRank_; - else - isShared_[it->localIdx] = true; - } - - // overwrite the master rank of the non-shared border on the - // domestic overlap - it = domesticBorderList_.begin(); - endIt = domesticBorderList_.end(); - for (; it != endIt; ++it) { - if (!it->isShared) { - masterRank_[it->localIdx] = it->peerRank; - } - } - } - - - // extend the foreign overlaps by one level. this uses a greedy - // algorithm. - void extendForeignOverlap_(const BCRSMatrix &A, - SeedList &seedList, - int overlapSize) - { - // add all processes in the seed rows of the current overlap - // level - int minOverlapDistance = overlapSize*2; - SeedList::const_iterator it = seedList.begin(); - SeedList::const_iterator endIt = seedList.end(); - for (; it != endIt; ++it) { - int localIdx = std::get<0>(*it); - int peerRank = std::get<1>(*it); - int distance = std::get<2>(*it); - if (foreignOverlapByIndex_[localIdx].count(peerRank) == 0) { - foreignOverlapByIndex_[localIdx][peerRank] = distance; - } - else { - foreignOverlapByIndex_[localIdx][peerRank] = - std::min(distance, - foreignOverlapByIndex_[localIdx][peerRank]); - } - - minOverlapDistance = std::min(minOverlapDistance, distance); - } - - // if we have reached the maximum overlap distance, we're - // finished and break the recursion - if (minOverlapDistance >= overlapSize) - return; - - // find the seed list for the next overlap level using the - // seed set for the current level - SeedList nextSeedList; - it = seedList.begin(); - for (; it != endIt; ++it) { - int rowIdx = std::get<0>(*it); - int peerRank = std::get<1>(*it); - int borderDist = std::get<2>(*it); - - // find all column indies in the row. The indices of the - // columns are the additional indices of the overlap which - // we would like to add - typedef typename BCRSMatrix::ConstColIterator ColIterator; - ColIterator colIt = A[rowIdx].begin(); - ColIterator colEndIt = A[rowIdx].end(); - for (; colIt != colEndIt; ++colIt) { - int newIdx = colIt.index(); - - // if the process is already is in the overlap of the - // column index, ignore this column index! - if (foreignOverlapByIndex_[newIdx].count(peerRank) > 0) - continue; - - - // check whether the new index is already in the overlap - bool hasIndex = false; - typename SeedList::iterator sIt = nextSeedList.begin(); - typename SeedList::iterator sEndIt = nextSeedList.end(); - for (; sIt != sEndIt; ++sIt) { - if (std::get<0>(*sIt) == newIdx && - std::get<1>(*sIt) == peerRank) - { - hasIndex = true; - std::get<2>(*sIt) = std::min(std::get<2>(*sIt), borderDist + 1); - break; - } - } - if (hasIndex) - continue; // we already have this index - - // add the current processes to the seed list for the - // next overlap level - IndexRankDist newTuple(newIdx, peerRank, borderDist + 1); - nextSeedList.push_back(newTuple); - } - } - - // clear the old seed list to save some memory - seedList.clear(); - - // Perform the same excercise for the next overlap distance - extendForeignOverlap_(A, - nextSeedList, - overlapSize); - } - - // assuming that the foreign overlap has been created for each - // local index, this method groups the foreign overlap by peer - // process rank - void groupForeignOverlapByRank_() - { - // loop over all indices which are in the overlap of some - // process - int nIndices = foreignOverlapByIndex_.size(); - for (int i = 0; i < nIndices; ++i) - { - // loop over the list of processes for the current index - std::map<ProcessRank, BorderDistance>::const_iterator it = - foreignOverlapByIndex_[i].begin(); - std::map<ProcessRank, BorderDistance>::const_iterator endIt = - foreignOverlapByIndex_[i].end(); - int nRanks = foreignOverlapByIndex_[i].size(); - for (; it != endIt; ++it) { - IndexDistanceNpeers tmp(i, it->second, nRanks); - foreignOverlapByRank_[it->first].push_back(tmp); - } - } - } - - // set of processes with which we have to communicate - PeerSet peerSet_; - - // the list of indices on the border - const BorderList &foreignBorderList_; - const BorderList &domesticBorderList_; - - // an array which contains the rank of the master process for each - // index - std::vector<ProcessRank> masterRank_; - - // an array which stores whether an index is also in the interior - // of some other process - std::vector<bool> isShared_; - - // set of all local indices which are on the border of some remote - // process - std::set<LocalIndex> borderIndices_; - - // stores the set of process ranks which are in the overlap for a - // given row index "owned" by the current rank. The second value - // store the distance from the nearest process border. - ForeignOverlapByIndex foreignOverlapByIndex_; - - // stores a list of foreign overlap indices for each rank - ForeignOverlapByRank foreignOverlapByRank_; - - // extend of the overlap region - int overlapSize_; - - // number of local indices - int numLocal_; - - // the MPI rank of the local process - int myRank_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/globalindices.hh b/dumux/linear/globalindices.hh deleted file mode 100644 index aa67af8544..0000000000 --- a/dumux/linear/globalindices.hh +++ /dev/null @@ -1,351 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief This class maps domestic row indices to and from "global" - * indices which is used to construct an algebraic overlap - * for the parallel linear solvers. - */ -#ifndef DUMUX_GLOBAL_INDICES_HH -#define DUMUX_GLOBAL_INDICES_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <list> -#include <set> -#include <map> - -#if HAVE_MPI -#include <mpi.h> -#endif - -#include <dune/common/fmatrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/scalarproducts.hh> -#include <dune/istl/operators.hh> - -#include "borderindex.hh" - -namespace Dumux { - -/*! - * \brief This class maps domestic row indices to and from "global" - * indices which is used to construct an algebraic overlap - * for the parallel linear solvers. - */ -template <class ForeignOverlap> -class GlobalIndices -{ - GlobalIndices(const GlobalIndices &A) - {} - - typedef int ProcessRank; - typedef int Index; - - typedef std::set<ProcessRank> PeerSet; - - - typedef std::list<BorderIndex> BorderList; - - - typedef std::map<Index, Index> GlobalToDomesticMap; - typedef std::map<Index, Index> DomesticToGlobalMap; - -public: - GlobalIndices(const ForeignOverlap &foreignOverlap) - : foreignOverlap_(foreignOverlap) - { - myRank_ = 0; - mpiSize_ = 1; - -#if HAVE_MPI - MPI_Comm_rank(MPI_COMM_WORLD, &myRank_); - MPI_Comm_size(MPI_COMM_WORLD, &mpiSize_); -#endif - - // calculate the domestic overlap (i.e. all overlap indices in - // foreign processes which the current process overlaps.) - // This requires communication via MPI. - buildGlobalIndices_(); - } - - /*! - * \brief Converts a domestic index to a global one. - */ - int domesticToGlobal(int domesticIdx) const - { - assert(domesticToGlobal_.find(domesticIdx) != domesticToGlobal_.end()); - - return domesticToGlobal_.find(domesticIdx)->second; - } - - /*! - * \brief Converts a global index to a domestic one. - */ - int globalToDomestic(int globalIdx) const - { - assert(globalToDomestic_.find(globalIdx) != globalToDomestic_.end()); - - return globalToDomestic_.find(globalIdx)->second; - }; - - /*! - * \brief Returns the number of indices which are in the interior or - * on the border of the current rank. - */ - int numLocal() const - { return foreignOverlap_.numLocal(); } - - /*! - * \brief Returns the number domestic indices. - * - * The domestic indices are defined as the process' local indices - * plus its copies of indices in the overlap regions - */ - int numDomestic() const - { - return numDomestic_; - } - - /*! - * \brief Add an index to the domestic<->global mapping. - */ - void addIndex(int domesticIdx, int globalIdx) - { - domesticToGlobal_[domesticIdx] = globalIdx; - globalToDomestic_[globalIdx] = domesticIdx; - numDomestic_ = domesticToGlobal_.size(); - - assert(domesticToGlobal_.size() == globalToDomestic_.size()); - }; - - /*! - * \brief Send a border index to a remote process. - */ - void sendBorderIndex(int peerRank, int domesticIdx, int peerLocalIdx) - { -#if HAVE_MPI - int sendBuff[2]; - sendBuff[0] = peerLocalIdx; - sendBuff[1] = domesticToGlobal(domesticIdx); - MPI_Send(sendBuff, // buff - 2, // count - MPI_INT, // data type - peerRank, - 0, // tag - MPI_COMM_WORLD); // communicator -#endif // HAVE_MPI - }; - - /*! - * \brief Receive an index on the border from a remote - * process and add it the translation maps. - */ - void receiveBorderIndex(int peerRank) - { -#if HAVE_MPI - int recvBuff[2]; - MPI_Recv(recvBuff, // buff - 2, // count - MPI_INT, // data type - peerRank, - 0, // tag - MPI_COMM_WORLD, // communicator - MPI_STATUS_IGNORE); // status - - int domesticIdx = recvBuff[0]; - int globalIdx = recvBuff[1]; - addIndex(domesticIdx, globalIdx); -#endif // HAVE_MPI - }; - - /*! - * \brief Return true iff a given global index already exists - */ - bool hasGlobalIndex(int globalIdx) const - { return globalToDomestic_.find(globalIdx) != globalToDomestic_.end(); }; - - /*! - * \brief Prints the global indices of all domestic indices - * for debugging purposes. - */ - void print() const - { - std::cout << "(domestic index, global index, domestic->global->domestic) list for rank " << - myRank_ << "\n"; - - for (int domIdx = 0; domIdx < domesticToGlobal_.size(); ++ domIdx) { - std::cout << "(" << domIdx - << ", " << domesticToGlobal(domIdx) - << ", " << globalToDomestic(domesticToGlobal(domIdx)) - << ") "; - } - std::cout << "\n"; - }; - -protected: - // retrieve the offset for the indices where we are master in the - // global index list - void buildGlobalIndices_() - { -#if HAVE_MPI - numDomestic_ = 0; -#else - numDomestic_ = foreignOverlap_.numLocal(); -#endif - -#if HAVE_MPI - if (myRank_ == 0) { - // the first rank starts at index zero - domesticOffset_ = 0; - } - else { - // all other ranks retrieve their offset from the next - // lower rank - MPI_Recv(&domesticOffset_, // buffer - 1, // count - MPI_INT, // data type - myRank_ - 1, - 0, // tag - MPI_COMM_WORLD, // communicator - MPI_STATUS_IGNORE); - } - - // create maps for all master indices - int numMaster = 0; - for (int i = 0; i < foreignOverlap_.numLocal(); ++i) { - if (!foreignOverlap_.iAmMasterOf(i)) { - continue; - } - - addIndex(i, domesticOffset_ + numMaster); - ++ numMaster; - } - - if (myRank_ < mpiSize_ - 1) { - // send the domestic offset plus the number of master - // indices to the process which is one rank higher - // all other ranks retrieve their offset from the next - // lower rank - int tmp = domesticOffset_ + numMaster; - MPI_Send(&tmp, // buff - 1, // count - MPI_INT, // data type - myRank_ + 1, // peer rank - 0, // tag - MPI_COMM_WORLD); // communicator - } - - typename PeerSet::const_iterator peerIt; - typename PeerSet::const_iterator peerEndIt = peerSet_().end(); - // receive the border indices from the lower ranks - peerIt = peerSet_().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - if (*peerIt < myRank_) - receiveBorderFrom_(*peerIt); - } - - // send the border indices to the higher ranks - peerIt = peerSet_().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - if (*peerIt > myRank_) - sendBorderTo_(*peerIt); - } - - // receive the border indices from the higher ranks - peerIt = peerSet_().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - if (*peerIt > myRank_) - receiveBorderFrom_(*peerIt); - } - - // send the border indices to the lower ranks - peerIt = peerSet_().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - if (*peerIt < myRank_) - sendBorderTo_(*peerIt); - } -#endif // HAVE_MPI - } - - void sendBorderTo_(ProcessRank peerRank) - { -#if HAVE_MPI - // send (local index on myRank, global index) pairs to the - // peers - BorderList::const_iterator borderIt = foreignBorderList_().begin(); - BorderList::const_iterator borderEndIt = foreignBorderList_().end(); - for (; borderIt != borderEndIt; ++borderIt) { - int borderPeer = borderIt->peerRank; - if (borderPeer != peerRank) - continue; - - int localIdx = borderIt->localIdx; - int peerIdx = borderIt->peerIdx; - if (foreignOverlap_.iAmMasterOf(borderIt->localIdx)) { - sendBorderIndex(borderPeer, localIdx, peerIdx); - } - } -#endif // HAVE_MPI - } - - void receiveBorderFrom_(ProcessRank peerRank) - { -#if HAVE_MPI - // retrieve the global indices for which we are not master - // from the processes with lower rank - BorderList::const_iterator borderIt = domesticBorderList_().begin(); - BorderList::const_iterator borderEndIt = domesticBorderList_().end(); - for (; borderIt != borderEndIt; ++borderIt) { - int borderPeer = borderIt->peerRank; - if (borderPeer != peerRank) - continue; - - if (foreignOverlap_.masterOf(borderIt->localIdx) == borderPeer) { - receiveBorderIndex(borderPeer); - } - } -#endif // HAVE_MPI - }; - - const PeerSet &peerSet_() const - { return foreignOverlap_.peerSet(); } - - const BorderList &foreignBorderList_() const - { return foreignOverlap_.foreignBorderList(); } - - const BorderList &domesticBorderList_() const - { return foreignOverlap_.domesticBorderList(); } - - - int myRank_; - int mpiSize_; - - int domesticOffset_; - int numDomestic_; - const ForeignOverlap &foreignOverlap_; - - GlobalToDomesticMap globalToDomestic_; - DomesticToGlobalMap domesticToGlobal_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/overlappingbcrsmatrix.hh b/dumux/linear/overlappingbcrsmatrix.hh deleted file mode 100644 index 62905197ba..0000000000 --- a/dumux/linear/overlappingbcrsmatrix.hh +++ /dev/null @@ -1,589 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief A BCRS matrix which creates an algebraic overlap of - * arbitrary size. - */ -#ifndef DUMUX_OVERLAPPING_BCRS_MATRIX_HH -#define DUMUX_OVERLAPPING_BCRS_MATRIX_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <algorithm> -#include <list> -#include <set> -#include <map> -#include <memory> - -#include <dune/istl/scalarproducts.hh> -#include <dune/istl/io.hh> - -#include <dumux/linear/domesticoverlapfrombcrsmatrix.hh> -#include <dumux/linear/globalindices.hh> -#include <dumux/parallel/mpibuffer.hh> - -namespace Dumux { - -template <class BCRSMatrix> -class OverlappingBCRSMatrix : public BCRSMatrix -{ - typedef BCRSMatrix ParentType; - -public: - typedef Dumux::DomesticOverlapFromBCRSMatrix<BCRSMatrix> Overlap; - -private: - typedef typename Overlap::Index Index; - typedef typename Overlap::Index ColIndex; - typedef typename Overlap::PeerSet PeerSet; - typedef typename Overlap::BorderList BorderList; - typedef typename Overlap::ProcessRank ProcessRank; - typedef typename Overlap::ForeignOverlapWithPeer ForeignOverlapWithPeer; - - typedef std::vector<std::set<ColIndex> > Entries; - -public: - typedef typename ParentType::ColIterator ColIterator; - typedef typename ParentType::ConstColIterator ConstColIterator; - typedef typename ParentType::block_type block_type; - - - // no real copying done at the moment - OverlappingBCRSMatrix(const OverlappingBCRSMatrix &M) - : ParentType(M) - { - } - - OverlappingBCRSMatrix(const BCRSMatrix &M, - const BorderList &foreignBorderList, - const BorderList &domesticBorderList, - int overlapSize) - { - overlap_ = std::make_shared<Overlap>(M, foreignBorderList, domesticBorderList, overlapSize); - myRank_ = 0; -#if HAVE_MPI - MPI_Comm_rank(MPI_COMM_WORLD, &myRank_); -#endif // HAVE_MPI - - // build the overlapping matrix from the non-overlapping - // matrix and the overlap - build_(M); - } - - /*! - * \brief Returns the domestic overlap for the process. - */ - const Overlap &overlap() const - { return *overlap_; } - - /*! - * \brief Assign and syncronize the overlapping matrix from a - * non-overlapping one. - */ - void assignAdd(const BCRSMatrix &M) - { - // first, set everything to 0 - BCRSMatrix::operator=(0.0); - - // assign the local rows - for (unsigned int rowIdx = 0; rowIdx < M.N(); ++rowIdx) { - ConstColIterator colIt = M[rowIdx].begin(); - ConstColIterator colEndIt = M[rowIdx].end(); - ColIterator myColIt = (*this)[rowIdx].begin(); - for (; colIt != colEndIt; ++colIt) { - while (true) { - if (myColIt.index() == colIt.index()) - break; - - ++ myColIt; - } - assert(myColIt.index() == colIt.index()); - - (*myColIt) = *colIt; - } - } - - // communicate and add the contents of overlapping rows - syncAdd_(); - } - - /*! - * \brief Assign and syncronize the overlapping matrix from a - * non-overlapping one. - * - * The non-master entries are copied from the master - */ - void assignCopy(const BCRSMatrix &M) - { - // first, set everything to 0 - BCRSMatrix::operator=(0.0); - - // assign the local rows - for (int rowIdx = 0; rowIdx < M.N(); ++rowIdx) { - ConstColIterator colIt = M[rowIdx].begin(); - ConstColIterator colEndIt = M[rowIdx].end(); - ColIterator myColIt = (*this)[rowIdx].begin(); - for (; colIt != colEndIt; ++colIt) { - while (true) { - if (myColIt.index() == colIt.index()) - break; - - ++ myColIt; - } - assert(myColIt.index() == colIt.index()); - - (*myColIt) = *colIt; - } - } - - // communicate and add the contents of overlapping rows - syncCopy_(); - } - - void print() const - { - overlap_->print(); - - for (int i = 0; i < this->N(); ++i) { - if (overlap_->isLocal(i)) - std::cout << " "; - else - std::cout << "*"; - std::cout << "row " << i << " "; - - typedef typename BCRSMatrix::ConstColIterator ColIt; - ColIt colIt = (*this)[i].begin(); - ColIt colEndIt = (*this)[i].end(); - for (int j = 0; j < this->M(); ++j) { - if (colIt != colEndIt && j == colIt.index()) { - ++colIt; - if (overlap_->isBorder(j)) - std::cout << "|"; - else if (overlap_->isLocal(j)) - std::cout << "X"; - else - std::cout << "*"; - } - else - std::cout << " "; - } - std::cout << "\n"; - } - Dune::printmatrix(std::cout, *static_cast<const BCRSMatrix*>(this), "M", "row"); - } - -private: - void build_(const BCRSMatrix &M) - { - int numDomestic = overlap_->numDomestic(); - - // allocate the rows - this->setSize(numDomestic, numDomestic); - this->setBuildMode(ParentType::random); - - // communicate the entries - buildIndices_(M); - } - - int numDomesticEntriesInRowFor_(const BCRSMatrix &M, int peerRank, int rowIdx) - { - int numEntries = 0; - - typedef typename BCRSMatrix::ConstColIterator ColIt; - ColIt colIt = M[rowIdx].begin(); - ColIt colEndIt = M[rowIdx].end(); - for (; colIt != colEndIt; ++colIt) { - if (overlap_->isDomesticIndexFor(peerRank, colIt.index())) - ++numEntries; - } - - return numEntries; - } - - void buildIndices_(const BCRSMatrix &M) - { - ///////// - // first, add all local matrix entries - ///////// - entries_.resize(overlap_->numDomestic()); - for (unsigned int rowIdx = 0; rowIdx < M.N(); ++rowIdx) { - ConstColIterator colIt = M[rowIdx].begin(); - ConstColIterator colEndIt = M[rowIdx].end(); - for (; colIt != colEndIt; ++colIt) { - entries_[rowIdx].insert(colIt.index()); - } - } - - ///////// - // add the indices for all additional entries - ///////// - - // first, send all our indices to all peers - const PeerSet &peerSet = overlap_->foreignOverlap().peerSet(); - typename PeerSet::const_iterator peerIt = peerSet.begin(); - typename PeerSet::const_iterator peerEndIt = peerSet.end(); - for (; peerIt != peerEndIt; ++peerIt) { - unsigned int peerRank = *peerIt; - sendRowIndices_(M, peerRank); - } - - // then recieve all indices from the peers - peerIt = peerSet.begin(); - for (; peerIt != peerEndIt; ++peerIt) { - unsigned int peerRank = *peerIt; - receiveRowIndices_(peerRank); - } - - // wait until all send operations are completed - peerIt = peerSet.begin(); - for (; peerIt != peerEndIt; ++peerIt) { - unsigned int peerRank = *peerIt; - - numRowsSendBuff_[peerRank]->wait(); - rowSizesSendBuff_[peerRank]->wait(); - rowIndicesSendBuff_[peerRank]->wait(); - entryIndicesSendBuff_[peerRank]->wait(); - - // convert the global indices in the send buffers to domestic - // ones - globalToDomesticBuff_(*rowIndicesSendBuff_[peerRank]); - globalToDomesticBuff_(*entryIndicesSendBuff_[peerRank]); - } - - ///////// - // actually initialize the BCRS matrix structure - ///////// - - // set the row sizes - unsigned int numDomestic = overlap_->numDomestic(); - for (unsigned int rowIdx = 0; rowIdx < numDomestic; ++rowIdx) { - this->setrowsize(rowIdx, entries_[rowIdx].size()); - } - this->endrowsizes(); - - // set the indices - for (unsigned int rowIdx = 0; rowIdx < numDomestic; ++rowIdx) { - const std::set<ColIndex> &colIndices = entries_[rowIdx]; - - typename std::set<ColIndex>::const_iterator colIdxIt = colIndices.begin(); - typename std::set<ColIndex>::const_iterator colIdxEndIt = colIndices.end(); - for (; colIdxIt != colIdxEndIt; ++colIdxIt) - this->addindex(rowIdx, *colIdxIt); - } - this->endindices(); - - // free the memory occupied by the array of the matrix entries - entries_.resize(0); - } - - // send the overlap indices to a peer - void sendRowIndices_(const BCRSMatrix &M, int peerRank) - { -#if HAVE_MPI - // send the number of non-border entries in the matrix - const ForeignOverlapWithPeer &peerOverlap = overlap_->foreignOverlapWithPeer(peerRank); - - // send size of foreign overlap to peer - int numOverlapRows = peerOverlap.size(); - numRowsSendBuff_[peerRank] = std::make_shared<MpiBuffer<int> >(1); - (*numRowsSendBuff_[peerRank])[0] = numOverlapRows; - numRowsSendBuff_[peerRank]->send(peerRank); - - rowSizesSendBuff_[peerRank] = std::make_shared<MpiBuffer<Index> >(numOverlapRows); - rowIndicesSendBuff_[peerRank] = std::make_shared<MpiBuffer<Index> >(numOverlapRows); - - // create the row size MPI buffer - int numEntries = 0; - typename ForeignOverlapWithPeer::const_iterator it = peerOverlap.begin(); - typename ForeignOverlapWithPeer::const_iterator endIt = peerOverlap.end(); - int i = 0; - for (; it != endIt; ++it, ++i) { - int rowIdx = std::get<0>(*it); - assert(overlap_->isDomesticIndexFor(peerRank, rowIdx)); - - typedef typename BCRSMatrix::ConstColIterator ColIt; - ColIt colIt = M[rowIdx].begin(); - ColIt colEndIt = M[rowIdx].end(); - int j = 0; - for (; colIt != colEndIt; ++colIt) { - if (overlap_->isDomesticIndexFor(peerRank, colIt.index())) { - ++ j; - } - } - - (*rowSizesSendBuff_[peerRank])[i] = j; - (*rowIndicesSendBuff_[peerRank])[i] = overlap_->domesticToGlobal(rowIdx); - numEntries += j; - } - - // actually communicate with the peer - rowIndicesSendBuff_[peerRank]->send(peerRank); - rowSizesSendBuff_[peerRank]->send(peerRank); - - // create and fill the MPI buffer for the indices of the - // matrix entries - entryIndicesSendBuff_[peerRank] = std::make_shared<MpiBuffer<Index> >(numEntries); - i = 0; - it = peerOverlap.begin(); - for (; it != endIt; ++it) { - int rowIdx = std::get<0>(*it); - assert(overlap_->isDomesticIndexFor(peerRank, rowIdx)); - - typedef typename BCRSMatrix::ConstColIterator ColIt; - ColIt colIt = M[rowIdx].begin(); - ColIt colEndIt = M[rowIdx].end(); - for (; colIt != colEndIt; ++colIt) { - if (overlap_->isDomesticIndexFor(peerRank, colIt.index())) { - (*entryIndicesSendBuff_[peerRank])[i] = overlap_->domesticToGlobal(colIt.index()); - ++i; - } - } - } - entryIndicesSendBuff_[peerRank]->send(peerRank); - - // create the send buffers for the values of the matrix - // entries - entryValuesSendBuff_[peerRank] = std::make_shared<MpiBuffer<block_type> >(numEntries); -#endif // HAVE_MPI - } - - // receive the overlap indices to a peer - void receiveRowIndices_(int peerRank) - { -#if HAVE_MPI - // receive size of foreign overlap to peer - int numOverlapRows; - MpiBuffer<int> numRowsRecvBuff(1); - numRowsRecvBuff.receive(peerRank); - numOverlapRows = numRowsRecvBuff[0]; - - // create receive buffer for the row sizes and receive them - // from the peer - rowIndicesRecvBuff_[peerRank] = std::make_shared<MpiBuffer<Index> >(numOverlapRows); - rowSizesRecvBuff_[peerRank] = std::make_shared<MpiBuffer<int> >(numOverlapRows); - rowIndicesRecvBuff_[peerRank]->receive(peerRank); - rowSizesRecvBuff_[peerRank]->receive(peerRank); - - // calculate the total number of indices which are send by the - // peer - int totalIndices = 0; - for (int i = 0; i < numOverlapRows; ++ i) { - totalIndices += (*rowSizesRecvBuff_[peerRank])[i]; - } - - // create the buffer to store the column indices of the matrix entries - entryIndicesRecvBuff_[peerRank] = std::make_shared<MpiBuffer<Index> >(totalIndices); - entryValuesRecvBuff_[peerRank] = std::make_shared<MpiBuffer<block_type> >(totalIndices); - - // communicate with the peer - entryIndicesRecvBuff_[peerRank]->receive(peerRank); - - // convert the global indices in the receive buffers to - // domestic ones - globalToDomesticBuff_(*rowIndicesRecvBuff_[peerRank]); - globalToDomesticBuff_(*entryIndicesRecvBuff_[peerRank]); - - // add the entries to the global entry map - int k = 0; - for (int i = 0; i < numOverlapRows; ++ i) { - int domRowIdx = (*rowIndicesRecvBuff_[peerRank])[i]; - for (int j = 0; j < (*rowSizesRecvBuff_[peerRank])[i]; ++j) { - int domColIdx = (*entryIndicesRecvBuff_[peerRank])[k]; - entries_[domRowIdx].insert(domColIdx); - ++k; - } - } -#endif // HAVE_MPI - } - - // communicates and adds up the contents of overlapping rows - void syncAdd_() - { - // first, send all entries to the peers - const PeerSet &peerSet = overlap_->foreignOverlap().peerSet(); - typename PeerSet::const_iterator peerIt = peerSet.begin(); - typename PeerSet::const_iterator peerEndIt = peerSet.end(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - - sendEntries_(peerRank); - } - - // then, receive entries from the peers - peerIt = peerSet.begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - - receiveAddEntries_(peerRank); - } - - // finally, make sure that everything which we send was - // received by the peers - peerIt = peerSet.begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - entryValuesSendBuff_[peerRank]->wait(); - } - } - - // communicates and copies the contents of overlapping rows from - // the master - void syncCopy_() - { - // first, send all entries to the peers - const PeerSet &peerSet = overlap_->foreignOverlap().peerSet(); - typename PeerSet::const_iterator peerIt = peerSet.begin(); - typename PeerSet::const_iterator peerEndIt = peerSet.end(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - - sendEntries_(peerRank); - } - - // then, receive entries from the peers - peerIt = peerSet.begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - - receiveCopyEntries_(peerRank); - } - - // finally, make sure that everything which we send was - // received by the peers - peerIt = peerSet.begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - entryValuesSendBuff_[peerRank]->wait(); - } - } - - void sendEntries_(int peerRank) - { -#if HAVE_MPI - MpiBuffer<block_type> &mpiSendBuff = *entryValuesSendBuff_[peerRank]; - - MpiBuffer<int> &mpiRowIndicesSendBuff = *rowIndicesSendBuff_[peerRank]; - MpiBuffer<int> &mpiRowSizesSendBuff = *rowSizesSendBuff_[peerRank]; - MpiBuffer<int> &mpiColIndicesSendBuff = *entryIndicesSendBuff_[peerRank]; - - // fill the send buffer - int k = 0; - for (int i = 0; i < mpiRowIndicesSendBuff.size(); ++i) { - Index domRowIdx = mpiRowIndicesSendBuff[i]; - - typedef typename ParentType::ConstColIterator ColIt; - ColIt colIt = (*this)[domRowIdx].begin(); - for (int j = 0; j < mpiRowSizesSendBuff[i]; ++j) { - Index domColIdx = mpiColIndicesSendBuff[k]; - for (; colIt.index() < domColIdx; ++colIt) - { } - assert(colIt.index() == domColIdx); - - mpiSendBuff[k] = (*colIt); - ++ k; - } - } - - mpiSendBuff.send(peerRank); -#endif // HAVE_MPI - } - - void receiveAddEntries_(int peerRank) - { -#if HAVE_MPI - MpiBuffer<block_type> &mpiRecvBuff = *entryValuesRecvBuff_[peerRank]; - - MpiBuffer<int> &mpiRowIndicesRecvBuff = *rowIndicesRecvBuff_[peerRank]; - MpiBuffer<int> &mpiRowSizesRecvBuff = *rowSizesRecvBuff_[peerRank]; - MpiBuffer<int> &mpiColIndicesRecvBuff = *entryIndicesRecvBuff_[peerRank]; - - mpiRecvBuff.receive(peerRank); - - // retrieve the values from the receive buffer - int k = 0; - for (int i = 0; i < mpiRowIndicesRecvBuff.size(); ++i) { - Index domRowIdx = mpiRowIndicesRecvBuff[i]; - for (int j = 0; j < mpiRowSizesRecvBuff[i]; ++j) { - Index domColIdx = mpiColIndicesRecvBuff[k]; - - (*this)[domRowIdx][domColIdx] += mpiRecvBuff[k]; - ++ k; - } - } -#endif // HAVE_MPI - } - - void receiveCopyEntries_(int peerRank) - { -#if HAVE_MPI - MpiBuffer<block_type> &mpiRecvBuff = *entryValuesRecvBuff_[peerRank]; - - MpiBuffer<int> &mpiRowIndicesRecvBuff = *rowIndicesRecvBuff_[peerRank]; - MpiBuffer<int> &mpiRowSizesRecvBuff = *rowSizesRecvBuff_[peerRank]; - MpiBuffer<int> &mpiColIndicesRecvBuff = *entryIndicesRecvBuff_[peerRank]; - - mpiRecvBuff.receive(peerRank); - - // retrieve the values from the receive buffer - int k = 0; - for (int i = 0; i < mpiRowIndicesRecvBuff.size(); ++i) { - Index domRowIdx = mpiRowIndicesRecvBuff[i]; - for (int j = 0; j < mpiRowSizesRecvBuff[i]; ++j) { - Index domColIdx = mpiColIndicesRecvBuff[k]; - - if (!overlap_->iAmMasterOf(domRowIdx) || - !overlap_->iAmMasterOf(domColIdx)) - { - (*this)[domRowIdx][domColIdx] = mpiRecvBuff[k]; - } - - ++ k; - } - } -#endif // HAVE_MPI - } - - void globalToDomesticBuff_(MpiBuffer<Index> &idxBuff) - { - for (int i = 0; i < idxBuff.size(); ++i) { - idxBuff[i] = overlap_->globalToDomestic(idxBuff[i]); - } - } - - int myRank_; - Entries entries_; - std::shared_ptr<Overlap> overlap_; - - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > rowSizesRecvBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > rowIndicesRecvBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > entryIndicesRecvBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<block_type> > > entryValuesRecvBuff_; - - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > numRowsSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > rowSizesSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > rowIndicesSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<int> > > entryIndicesSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<block_type> > > entryValuesSendBuff_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/overlappingblockvector.hh b/dumux/linear/overlappingblockvector.hh deleted file mode 100644 index eda7c843ba..0000000000 --- a/dumux/linear/overlappingblockvector.hh +++ /dev/null @@ -1,458 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief A block vector which creates an algebraic overlap of - * arbitrary size. - */ -#ifndef DUMUX_OVERLAPPING_BLOCK_VECTOR_HH -#define DUMUX_OVERLAPPING_BLOCK_VECTOR_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <iostream> -#include <map> -#include <memory> -#include <vector> - -#include <dune/istl/bvector.hh> - -#include <dumux/parallel/mpibuffer.hh> -#include <dumux/common/valgrind.hh> - -namespace Dumux { - -template <class FieldVector, class Overlap> -class OverlappingBlockVector - : public Dune::BlockVector<FieldVector> -{ - typedef Dune::BlockVector<FieldVector> ParentType; - typedef Dune::BlockVector<FieldVector> BlockVector; - - typedef typename Overlap::Index RowIndex; - typedef typename Overlap::ProcessRank ProcessRank; - typedef typename Overlap::PeerSet PeerSet; - typedef typename Overlap::DomesticOverlapWithPeer DomesticOverlapWithPeer; - - typedef typename ParentType::field_type Scalar; - -public: - OverlappingBlockVector(const Overlap &overlap) - : ParentType(overlap.numDomestic()) - , overlap_(&overlap) - { - createBuffers_(); - } - - /*! - * \brief Copy constructor. - */ - OverlappingBlockVector(const OverlappingBlockVector &obv) - : ParentType(obv) - , frontMaster_(obv.frontMaster_) - , numIndicesSendBuff_(obv.numIndicesSendBuff_) - , indicesSendBuff_(obv.indicesSendBuff_) - , indicesRecvBuff_(obv.indicesRecvBuff_) - , valuesSendBuff_(obv.valuesSendBuff_) - , valuesRecvBuff_(obv.valuesRecvBuff_) - , overlap_(obv.overlap_) - { - } - - ~OverlappingBlockVector() - { - } - - /*! - * \brief Assign an overlapping block vector from a - * non-overlapping one, border entries are added. - */ - void assignAdd(const BlockVector &nbv) - { - // assign the local rows - int numLocal = overlap_->numLocal(); - for (int rowIdx = 0; rowIdx < numLocal; ++rowIdx) { - if (overlap_->iAmMasterOf(rowIdx) || - overlap_->isShared(rowIdx)) - { - (*this)[rowIdx] = nbv[rowIdx]; - } - else - (*this)[rowIdx] = 0; - - } - - // set the remote indices to 0 - int numDomestic = overlap_->numDomestic(); - for (int rowIdx = numLocal; rowIdx < numDomestic; ++rowIdx) { - (*this)[rowIdx] = 0; - } - - // add up the contents of overlapping rows - syncAdd(); - } - - /*! - * \brief Assign the local values to a non-overlapping block - * vector. - */ - void assignTo(BlockVector &nbv) const - { - // assign the local rows - int numLocal = overlap_->numLocal(); - for (int rowIdx = 0; rowIdx < numLocal; ++rowIdx) { - nbv[rowIdx] = (*this)[rowIdx]; - } - } - - /*! - * \brief Syncronize an overlapping block vector by adding up all - * overlapping entries. - */ - void syncAdd() - { - typename PeerSet::const_iterator peerIt; - typename PeerSet::const_iterator peerEndIt = overlap_->peerSet().end(); - - // send all entries to all peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - sendEntries_(peerRank); - } - - // recieve all entries to the peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - receiveAddEntries_(peerRank); - } - - // wait until we have send everything - waitSendFinished_(); - } - - /*! - * \brief Syncronize the block vector by taking the arithmetic - * mean of all entries which are not on the front of some - * process - * - * \todo use specialized send methods for improved - * performance. (i.e. only send the front entries to the - * peers.) - */ - void syncAverageFrontFromMaster() - { - // first, reset all of our front rows - int numLocal = overlap_->numLocal(); - int numDomestic = overlap_->numDomestic(); - for (int i = numLocal; i < numDomestic; ++i) { - if (overlap_->isFront(i)) - (*this)[i] = 0; - } - - typename PeerSet::const_iterator peerIt; - typename PeerSet::const_iterator peerEndIt = overlap_->peerSet().end(); - - // send all entries to all peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - sendEntries_(peerRank); - } - - // recieve all entries to the peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - receiveAverageFrontFromMaster_(peerRank); - } - - // divide each entry by the number of non-front processes - for (int i = 0; i < numDomestic; ++i) { - (*this)[i] /= overlap_->numNonFrontProcesses(i); - } - - // wait until we have send everything - waitSendFinished_(); - } - - /*! - * \brief Syncronize an overlapping block vector by copying the - * front entries from their master process - * - * \todo use specialized send methods for improved - * performance. (i.e. only send the front entries to the - * peers.) - */ - void syncFrontFromMaster() - { - typename PeerSet::const_iterator peerIt; - typename PeerSet::const_iterator peerEndIt = overlap_->peerSet().end(); - - // send all entries to all peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - sendEntries_(peerRank); - } - - // recieve all entries to the peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - receiveFrontFromMaster_(peerRank); - } - - // wait until we have send everything - waitSendFinished_(); - } - - using ParentType::operator=; - /*! - * \brief Copy constructor. - */ - OverlappingBlockVector &operator=(const OverlappingBlockVector &obv) - { - ParentType::operator=(obv); - overlap_ = obv.overlap_; - return *this; - } - - /*! - * \brief Syncronize an overlapping block vector and take the - * arthmetic mean of the entry values of all processes. - */ - void syncAverage() - { - syncAdd(); - - int numDomestic = overlap_->numDomestic(); - for (int i = 0; i < numDomestic; ++i) { - (*this)[i] /= overlap_->numPeers(i) + 1; - } - } - - /*! - * \brief Set all front entities to a given scalar value - */ - void resetFront(Scalar value = 0.0) - { - int numDomestic = this->size(); - for (int i = 0; i < numDomestic; ++i) { - if (overlap_->isFront(i)) { - (*this)[i] = value; - } - } - } - - /*! - * \brief Set all remote entities to a given scalar value - */ - void resetRemote(Scalar value = 0.0) - { - int numDomestic = overlap_->numDomestic(); - for (int i = overlap_->numLocal(); i < numDomestic; ++i) { - (*this)[i] = value; - } - } - - void print() const - { - for (int i = 0; i < this->size(); ++i) { - std::cout << "row " << i << (overlap_->isLocal(i)?" ":"*") << ": " << (*this)[i] << "\n"; - } - } - -private: - void createBuffers_() - { -#if HAVE_MPI - // create array for the front indices - int numDomestic = overlap_->numDomestic(); - frontMaster_ = std::make_shared<std::vector<ProcessRank> >(numDomestic, -1); - - typename PeerSet::const_iterator peerIt; - typename PeerSet::const_iterator peerEndIt = overlap_->peerSet().end(); - - // send all indices to the peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - - const DomesticOverlapWithPeer &domesticOverlap = overlap_->domesticOverlapWithPeer(peerRank); - int numEntries = domesticOverlap.size(); - numIndicesSendBuff_[peerRank] = std::make_shared<MpiBuffer<int> >(1); - indicesSendBuff_[peerRank] = std::make_shared<MpiBuffer<RowIndex> >(numEntries); - valuesSendBuff_[peerRank] = std::make_shared<MpiBuffer<FieldVector> >(numEntries); - - // fill the indices buffer with global indices - MpiBuffer<RowIndex> &indicesSendBuff = *indicesSendBuff_[peerRank]; - typename DomesticOverlapWithPeer::const_iterator domIt = domesticOverlap.begin(); - typename DomesticOverlapWithPeer::const_iterator domEndIt = domesticOverlap.end(); - for (int i = 0; domIt != domEndIt; ++domIt, ++i) { - int rowIdx = *domIt; - indicesSendBuff[i] = overlap_->domesticToGlobal(rowIdx); - } - - // first, send the number of indices - (*numIndicesSendBuff_[peerRank])[0] = numEntries; - numIndicesSendBuff_[peerRank]->send(peerRank); - - // then, send the indices themselfs - indicesSendBuff.send(peerRank); - } - - // receive the indices from the peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - - // receive size of overlap to peer - int numRows; - MpiBuffer<int> numRowsRecvBuff(1); - numRowsRecvBuff.receive(peerRank); - numRows = numRowsRecvBuff[0]; - - // then, create the MPI buffers - indicesRecvBuff_[peerRank] = std::make_shared<MpiBuffer<RowIndex> >(numRows); - valuesRecvBuff_[peerRank] = std::make_shared<MpiBuffer<FieldVector> >(numRows); - MpiBuffer<RowIndex> &indicesRecvBuff = *indicesRecvBuff_[peerRank]; - - // next, receive the actual indices - indicesRecvBuff.receive(peerRank); - - // finally, translate the global indices to domestic ones - for (int i = 0; i != numRows; ++i) { - int globalRowIdx = indicesRecvBuff[i]; - int domRowIdx = overlap_->globalToDomestic(globalRowIdx); - indicesRecvBuff[i] = domRowIdx; - - if (overlap_->isFront(domRowIdx) && - overlap_->isMasterOf(peerRank, domRowIdx)) - { - (*frontMaster_)[domRowIdx] = peerRank; - } - } - } - - // wait for all send operations to complete - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - numIndicesSendBuff_[peerRank]->wait(); - indicesSendBuff_[peerRank]->wait(); - - // convert the global indices of the send buffer to - // domestic ones - MpiBuffer<RowIndex> &indicesSendBuff = *indicesSendBuff_[peerRank]; - for (int i = 0; i < indicesSendBuff.size(); ++i) { - indicesSendBuff[i] = overlap_->globalToDomestic(indicesSendBuff[i]); - } - } -#endif // HAVE_MPI - } - - void sendEntries_(int peerRank) - { - // copy the values into the send buffer - const MpiBuffer<RowIndex> &indices = *indicesSendBuff_[peerRank]; - MpiBuffer<FieldVector> &values = *valuesSendBuff_[peerRank]; - for (int i = 0; i < indices.size(); ++ i) - values[i] = (*this)[indices[i]]; - - values.send(peerRank); - } - - void waitSendFinished_() - { - typename PeerSet::const_iterator peerIt; - typename PeerSet::const_iterator peerEndIt = overlap_->peerSet().end(); - - // send all entries to all peers - peerIt = overlap_->peerSet().begin(); - for (; peerIt != peerEndIt; ++peerIt) { - int peerRank = *peerIt; - valuesSendBuff_[peerRank]->wait(); - } - } - - void receiveAddEntries_(int peerRank) - { - const MpiBuffer<RowIndex> &indices = *indicesRecvBuff_[peerRank]; - MpiBuffer<FieldVector> &values = *valuesRecvBuff_[peerRank]; - - // receive the values from the peer - values.receive(peerRank); - - // copy them into the block vector - for (int i = 0; i < indices.size(); ++ i) { - (*this)[indices[i]] += values[i]; - } - } - - void receiveFrontFromMaster_(int peerRank) - { - const MpiBuffer<RowIndex> &indices = *indicesRecvBuff_[peerRank]; - MpiBuffer<FieldVector> &values = *valuesRecvBuff_[peerRank]; - - // receive the values from the peer - values.receive(peerRank); - - // copy them into the block vector - for (int j = 0; j < indices.size(); ++j) { - int domRowIdx = indices[j]; - if ((*frontMaster_)[domRowIdx] != peerRank) - continue; - - (*this)[domRowIdx] = values[j]; - } - } - - void receiveAverageFrontFromMaster_(int peerRank) - { - const MpiBuffer<RowIndex> &indices = *indicesRecvBuff_[peerRank]; - MpiBuffer<FieldVector> &values = *valuesRecvBuff_[peerRank]; - - // receive the values from the peer - values.receive(peerRank); - - // copy them into the block vector - for (int j = 0; j < indices.size(); ++j) { - int domRowIdx = indices[j]; - (*this)[domRowIdx] += values[j]; - } - } - - std::shared_ptr<std::vector<ProcessRank> > frontMaster_; - - std::map<ProcessRank, std::shared_ptr<MpiBuffer<RowIndex> > > numIndicesSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<RowIndex> > > indicesSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<RowIndex> > > indicesRecvBuff_; - - std::map<ProcessRank, std::shared_ptr<MpiBuffer<FieldVector> > > valuesSendBuff_; - std::map<ProcessRank, std::shared_ptr<MpiBuffer<FieldVector> > > valuesRecvBuff_; - - const Overlap *overlap_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/overlappingoperator.hh b/dumux/linear/overlappingoperator.hh deleted file mode 100644 index b6862337d1..0000000000 --- a/dumux/linear/overlappingoperator.hh +++ /dev/null @@ -1,76 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief A overlapping linear operator for use with ISTL - */ -#ifndef DUMUX_OVERLAPPING_OPERATOR_HH -#define DUMUX_OVERLAPPING_OPERATOR_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <dune/istl/operators.hh> - -namespace Dumux { - -// operator that resets result to zero at constrained DOFS -template<class OverlappingMatrix, class DomainVector, class RangeVector> -class OverlappingOperator : - public Dune::AssembledLinearOperator<OverlappingMatrix, - DomainVector, - RangeVector> -{ -public: - //! export types - typedef DomainVector domain_type; - typedef typename domain_type::field_type field_type; - - //redefine the category, that is the only difference - enum {category=Dune::SolverCategory::overlapping}; - - OverlappingOperator (const OverlappingMatrix& A) - : A_(A) - {} - - //! apply operator to x: \f$ y = A(x) \f$ - virtual void apply (const DomainVector& x, RangeVector& y) const - { - A_.mv(x,y); - } - - //! apply operator to x, scale and add: \f$ y = y + \alpha A(x) \f$ - virtual void applyscaleadd(field_type alpha, const DomainVector& x, RangeVector& y) const - { - A_.usmv(alpha, x, y); - } - - //! returns the matrix - virtual const OverlappingMatrix& getmat() const - { - return A_; - } - -private: - const OverlappingMatrix &A_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/overlappingpreconditioner.hh b/dumux/linear/overlappingpreconditioner.hh deleted file mode 100644 index cd6a8312e2..0000000000 --- a/dumux/linear/overlappingpreconditioner.hh +++ /dev/null @@ -1,121 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief A preconditioner for overlapping matrices and vectors - */ -#ifndef DUMUX_OVERLAPPING_PRECONDITIONER_HH -#define DUMUX_OVERLAPPING_PRECONDITIONER_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include <dumux/common/exceptions.hh> -#include <dune/istl/preconditioners.hh> - -#include "overlappingscalarproduct.hh" - -namespace Dumux { - -template <class SeqPreCond, class Overlap> -class OverlappingPreconditioner : - public Dune::Preconditioner<typename SeqPreCond::domain_type, - typename SeqPreCond::range_type> -{ -public: - typedef typename SeqPreCond::domain_type domain_type; - typedef typename SeqPreCond::range_type range_type; - - enum { category = Dune::SolverCategory::overlapping }; - - OverlappingPreconditioner(SeqPreCond &seqPreCond, const Overlap &overlap) - : seqPreCond_(seqPreCond), overlap_(&overlap) - { - } - - void pre(domain_type &x, range_type &y) - { - seqPreCond_.pre(x, y); - -/* - // communicate the results on the overlap - x.syncAverage(); - y.syncAverage(); -*/ - }; - - void apply(domain_type &x, const range_type &d) - { -#if HAVE_MPI - if (overlap_->peerSet().size() > 0) { - // set the residual and right hand side on the front to zero - range_type dd(d); - dd.resetFront(); - - // make sure that all processes react the same if the - // sequential preconditioner on one process throws an - // exception - short success; - try { - // execute the sequential preconditioner - seqPreCond_.apply(x, dd); - short localSuccess = 1; - MPI_Allreduce(&localSuccess, // source buffer - &success, // destination buffer - 1, // number of objects in buffers - MPI_SHORT, // data type - MPI_MIN, // operation - MPI_COMM_WORLD); // communicator - } - catch (const Dune::Exception &e) { - std::cout << "Process " << overlap_->myRank() - << " threw exception in sequential preconditioner: " << e.what() << "\n"; - short localSuccess = 0; - MPI_Allreduce(&localSuccess, // source buffer - &success, // destination buffer - 1, // number of objects in buffers - MPI_SHORT, // data type - MPI_MIN, // operation - MPI_COMM_WORLD); // communicator - } - - if (success) - x.syncAverage(); - else - DUNE_THROW(NumericalProblem, - "Preconditioner threw an exception on some process."); - } - else -#endif // HAVE_MPI - seqPreCond_.apply(x, d); - }; - - void post(domain_type &x) - { - seqPreCond_.post(x); - }; - -private: - SeqPreCond seqPreCond_; - const Overlap *overlap_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/overlappingscalarproduct.hh b/dumux/linear/overlappingscalarproduct.hh deleted file mode 100644 index 9ff54469ee..0000000000 --- a/dumux/linear/overlappingscalarproduct.hh +++ /dev/null @@ -1,86 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief A scalar product for overlapping vectors - */ -#ifndef DUMUX_OVERLAPPING_SCALAR_PRODUCT_HH -#define DUMUX_OVERLAPPING_SCALAR_PRODUCT_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#if HAVE_MPI -#include <mpi.h> -#endif - -#include <dune/istl/scalarproducts.hh> - -namespace Dumux { - -template <class OverlappingBlockVector, class Overlap> -class OverlappingScalarProduct : public Dune::ScalarProduct<OverlappingBlockVector> -{ -public: - typedef typename OverlappingBlockVector::field_type field_type; - - enum { category = Dune::SolverCategory::overlapping }; - - OverlappingScalarProduct(const Overlap &overlap) - : overlap_(overlap) - {}; - - field_type dot(const OverlappingBlockVector &x, const OverlappingBlockVector &y) - { - double sum = 0; - int n = overlap_.numLocal(); - for (int i = 0; i < n; ++i) { - if (overlap_.iAmMasterOf(i)) - sum += x[i]*y[i]; - } - - // compute the global sum - double sumGlobal = 0.0; -#if HAVE_MPI - MPI_Allreduce(&sum, // source buffer - &sumGlobal, // destination buffer - 1, // number of objects in buffers - MPI_DOUBLE, // data type - MPI_SUM, // operation - MPI_COMM_WORLD); // communicator -#else - sumGlobal = sum; -#endif // HAVE_MPI - - return sumGlobal; - }; - - double norm(const OverlappingBlockVector &x) - { - double tmp = dot(x, x); - return std::sqrt(tmp); - }; - -private: - const Overlap &overlap_; -}; - -} // namespace Dumux - -#endif diff --git a/dumux/linear/vertexborderlistfromgrid.hh b/dumux/linear/vertexborderlistfromgrid.hh deleted file mode 100644 index 60f0dadca7..0000000000 --- a/dumux/linear/vertexborderlistfromgrid.hh +++ /dev/null @@ -1,122 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief Creates a list of vertex indices on the process border which - * can be used to construct the foreign overlap. - */ -#ifndef DUMUX_VERTEX_BORDER_LIST_FROM_GRID_HH -#define DUMUX_VERTEX_BORDER_LIST_FROM_GRID_HH - -#warning This file is deprecated and will be removed after Dumux 2.9 - -#include "borderindex.hh" - -#include <dune/grid/common/datahandleif.hh> -#include <dune/grid/common/gridenums.hh> -#include <dune/common/fmatrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/scalarproducts.hh> -#include <dune/istl/operators.hh> - -#include <algorithm> -#include <list> -#include <set> -#include <map> - -namespace Dumux { - -/*! - * \brief Uses communication on the grid to find the initial seed list - * of indices. - * - * \todo implement this class generically. For this, it must be - * possible to query the mapper whether it contains entities of - * a given codimension without the need to hand it an actual - * entity. - */ -template <class GridView, class VertexMapper> -class VertexBorderListFromGrid : public Dune::CommDataHandleIF<VertexBorderListFromGrid<GridView, VertexMapper>, - int > -{ - typedef std::list<BorderIndex> BorderList; - -public: - VertexBorderListFromGrid(const GridView &gridView, - const VertexMapper &map) - : gridView_(gridView), map_(map) - { - gridView.communicate(*this, - Dune::InteriorBorder_InteriorBorder_Interface, - Dune::ForwardCommunication); - }; - - // data handle methods - bool contains (int dim, int codim) const - { return dim == codim; } - - bool fixedsize(int dim, int codim) const - { return true; } - - template<class EntityType> - size_t size(const EntityType &e) const - { return 2; } - - template<class MessageBufferImp, class EntityType> - void gather(MessageBufferImp &buff, const EntityType &e) const - { - buff.write(gridView_.comm().rank()); - buff.write(static_cast<int>(map_.index(e))); - } - - template<class MessageBufferImp, class EntityType> - void scatter(MessageBufferImp &buff, const EntityType &e, size_t n) - { - BorderIndex bIdx; - - bIdx.localIdx = map_.index(e); - buff.read(bIdx.peerRank); - buff.read(bIdx.peerIdx); - bIdx.borderDistance = 0; - // vertices on the border are always in the interior of more - // than one process which means that they are shared. - bIdx.isShared = true; - - borderList_.push_back(bIdx); - } - - // Access to the foreign border list. - const BorderList &foreignBorderList() const - { return borderList_; } - - // Access to the domestic border list (same as foreign border list - // because all vertices are shared entities) - const BorderList &domesticBorderList() const - { return borderList_; } - -private: - const GridView gridView_; - const VertexMapper &map_; - BorderList borderList_; -}; - -} // namespace Dumux - -#endif -- GitLab