Commit c8a9a19e by Praetorius, Simon

### added Neumann problem as example

parent 601c4cb0
 ... ... @@ -240,6 +240,9 @@ inline auto scalar() * of any grid elements. On all bound elements the global index of any local DOF * is the index 0. * * The local finite-element is of type \ref P0LocalFiniteElement, i.e. a polynomial * basis of order 0. * * A ScalarBasis can be created with the factory \ref scalar(). * * See the following classes for details: ... ...
 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // vi: set et ts=4 sw=2 sts=2: #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** * This example implements the poisson equation with homogeneous neumann * boundary conditions and an average integral normalization: * *  * -\Delta u = f in domain, \\ * \int u = 0, \\ * \partial_n u = 0 on boundary *  **/ using namespace Dune; template void getLocalMatrix(const LocalView& localView, ElementMatrix& elementMatrix) { using Element = typename LocalView::Element; const Element element = localView.element(); const int dim = Element::dimension; auto geometry = element.geometry(); elementMatrix = 0; using namespace Indices; const auto& uLocalFE = localView.tree().child(_0).finiteElement(); const auto& sLocalFE = localView.tree().child(_1).finiteElement(); int order = 2*(dim*uLocalFE.localBasis().order()-1); const auto& quad = QuadratureRules::rule(element.type(), order); for (const auto& qp : quad) { const auto JinvT = geometry.jacobianInverseTransposed(qp.position()); const auto dx = geometry.integrationElement(qp.position()) * qp.weight(); thread_local std::vector > refGrads; uLocalFE.localBasis().evaluateJacobian(qp.position(), refGrads); thread_local std::vector > gradients; gradients.resize(refGrads.size()); for (std::size_t i=0; i > uValues; uLocalFE.localBasis().evaluateFunction(qp.position(), uValues); // int(u) == 0 condition for (std::size_t i=0; i void setOccupationPattern(const Basis& basis, MatrixType& matrix) { MatrixIndexSet nb(basis.dimension(), basis.dimension()); auto localView = basis.localView(); for(const auto& element : elements(basis.gridView())) { localView.bind(element); for (std::size_t i=0; i decltype(auto) matrixEntry(Matrix& matrix, const MultiIndex& row, const MultiIndex& col) { return matrix[row[0]][col[0]]; } template void assembleMatrix(const Basis& basis, MatrixType& matrix) { setOccupationPattern(basis, matrix); matrix = 0; auto localView = basis.localView(); Matrix > elementMatrix; elementMatrix.setSize(localView.maxSize(), localView.maxSize()); for (const auto& element : elements(basis.gridView())) { localView.bind(element); getLocalMatrix(localView, elementMatrix); for (std::size_t i=0; i; GridType grid({1.0, 1.0}, {4, 4}); using GridView = typename GridType::LeafGridView; GridView gridView = grid.leafGridView(); using namespace Functions::BasisFactory; auto basis = makeBasis(gridView, composite(lagrange<1>(), scalar(), flatLexicographic() )); using VectorType = BlockVector >; using MatrixType = BCRSMatrix >; VectorType rhs; auto rhsBackend = Dune::Functions::istlVectorBackend(rhs); rhsBackend.resize(basis); rhs = 0; using namespace Indices; Functions::interpolate( Functions::subspaceBasis(basis, _0), rhs, [](auto const& x) { return std::sin(x[0]*6*M_PI) + std::cos(x[1]*4*M_PI); }); MatrixType stiffnessMatrix; assembleMatrix(basis, stiffnessMatrix); MatrixAdapter stiffnessOperator(stiffnessMatrix); Richardson preconditioner(1.0); RestartedGMResSolver solver( stiffnessOperator, // operator to invert preconditioner, // preconditioner for interation 1e-10, // desired residual reduction factor 500, // number of iterations between restarts 500, // maximum number of iterations 2); // verbosity of the solver InverseOperatorResult statistics; VectorType x = rhs; solver.apply(x, rhs, statistics); }