Integrating functions on a grid¶
Integration is one of the most common tasks in PDE codes.
This page shows two practical approaches based on dune-grid and dune-geometry.
Learning goals
After this page, you should be able to:
- implement element-wise integration over a grid,
- compare midpoint and quadrature-based integration,
- use intersections for boundary contributions.
Problem¶
Given a function \(u\colon\Omega\to\mathbb{R}\), we want to compute the integral \(\int_\Omega u(x)\,dx\) over a grid domain \(\Omega\).
1. Midpoint rule¶
Use this as a simple and fast baseline integration method.
double integral = 0.0;
auto gv = grid.leafGridView();
auto u = [](const auto& x) { return std::exp(x.two_norm()); };
for (const auto& e : elements(gv))
{
const auto geo = e.geometry();
integral += u(geo.center()) * geo.volume();
}
This is easy and cheap, but only low-order accurate.
2. Quadrature rule¶
Use this for the standard finite-element integration workflow.
#include <dune/geometry/quadraturerules.hh>
double integral2 = 0.0;
constexpr int dim = Grid::dimension;
using QR = Dune::QuadratureRules<typename Grid::ctype, dim>;
for (const auto& e : elements(gv))
{
const auto geo = e.geometry();
const auto quadrature = QR::rule(geo.type(), 5); // order 5
for (const auto& qp : quadrature)
integral2 += u(geo.global(qp.position()))
* geo.integrationElement(qp.position())
* qp.weight();
}
This is the typical pattern used in element assembly.
3. Boundary fluxes via intersections¶
For boundary integrals, iterate over intersections and test boundary sides:
double flux = 0.0;
auto f = [](const auto& x) { return x; };
for (const auto& e : elements(gv))
for (const auto& is : intersections(gv, e))
if (is.boundary())
flux += f(is.geometry().center()) * is.centerUnitOuterNormal() * is.geometry().volume();
For a focused explanation of this interface, see Grid intersections.
Runnable example: examples/03_grid_integration/integration.cc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
Build and run:
source _env/activate.sh
cd examples/03_grid_integration
dunecontrol --current all
./build/debug/example03
Output:
elements: 256
midpoint integral = 0.8330078125
quadrature integral= 0.8333333333
exact integral = 0.8333333333
midpoint error = 0.0003255208
quadrature error = 0.0000000000
Source inspiration¶
This page is based on the DUNE grid recipe:
_material/dune-grid-recipes/recipe-integration.cc.
Summary and next steps¶
You now have the core integration loop patterns used in finite element assembly. Next, continue with Grid I/O and Grid info utilities.