Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
D
dune-dec
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 8
    • Issues 8
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Operations
    • Operations
    • Incidents
  • Analytics
    • Analytics
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar
  • Praetorius, Simon
  • dune-dec
  • Wiki
  • Home

Last edited by Praetorius, Simon May 14, 2017
Page history

Home

Examples

Poisson equation

We want to solve the Poisson equation

On the unit sphere, where the Laplacian is the Laplace-Beltrami operator. To close the equation, we need to fix at least one point x0.

For the grid, we use as input an ikosaeder mesh that is refined by division of each triangle into four parts, until the desired grid-width is reached. This grid is provided in the examples/grid directory, i.e. ikosaeder.3d in an ALBERTA grid format. For the quartering refinement of surface grids the Dune::FoamGrid backend is appropriate:

#include <dune/grid/albertagrid/albertareader.hh>
#include <dune/foamgrid/foamgrid.hh>

#include <dune/dec/DecGrid.hpp>

int main(int argc, char** argv)
{
  decpde::init(argc, argv);

  assert_msg( argc > 1, "usage: ", argv[0], " grid-filename [numRef]");

  using GridBase = Dune::FoamGrid<2, 3>;

  // read the grid from ALBERTA grid file
  Dune::GridFactory<GridBase> gridFactory;

  std::string filename = argv[1];
  Dune::AlbertaReader<GridBase>().readGrid(filename, gridFactory);
  std::unique_ptr<GridBase> gridBase( gridFactory.createGrid() );

  // create a grid adapter
  DecGrid<GridBase> grid(*gridBase);

Reading grid-files is done using a Dune::GridFactory. Thus, you can read GMsh files or ALBERTA files into any grid data-structure supporting your desired grid-entities. Dune-DEC requires an (oriented) well-centered simplicial grid. Starting from an ikosaeder grid a refinement by quartering guarantees the well-centeredness.

In order to refine a surface grid it is necessary to project the created vertices to the underlying surface. This needs a projection map. For some surfaces these are provided, e.g. for a sphere or a torus. Therefore, instead or reading into the grid directly, we have to pass the reader a projection adapter:

  using GridBase = Dune::FoamGrid<2, 3>;
  using Param = Parametrization<GridBase, SphereMapping<2, 3, UnitRadius>>;

  Dune::GridFactory<Param> gridFactory;
  Dune::AlbertaReader<Param>().readGrid(argv[1], gridFactory);
  std::unique_ptr<GridBase> gridBase( gridFactory.create() );

The class Parametrization is parametrized with the underlying grid-type and a mapping. This mapping is stored in the grid-elements to create projected points during refinement.

  DecGrid<GridBase> grid(*gridBase);
  grid.globalRefine(argc > 2 ? std::atoi(argv[2]) : 5);

Assembling the linear system

The Laplace-Beltrami operator is predefined in Dune-DEC and can be assembled directly. Therefore, we have to create a matrix first and an operator:

    DOFMatrix<double> A;
   
    // create a gridview, to specify for which element to assemble
    using GridView = typename Grid::LeafGridView;
    auto gv = grid.leafGridView();

    LaplaceBeltrami<GridView> laplace(gv);
    laplace.build(A);

    // create a rhs-vector with value 1 on all vertices
    DOFVector<double> f(gv, 0, 1.0);

The Laplace-Beltrami operator is defined on the vertices of the grid. This is a specialization of the more general Laplace-DeRham operator for 0-forms. The Matrix is initialized automatically during assembling of the linear system in the build() method. An operator provides additionally the methods init(), assemble(), and finish() to split up the build-process into three steps.

Boundary conditions

The enforcement of boundary-conditions, or in this case a point-wise condition, is a two-step procedure: 1. clear the row corresponding the DOF you want to specify the condition for. 2. Set the enforced value on the rhs-vector:

  auto boundary = {0};
  for (auto i : boundary) {
    A.clear_dirichlet_row(i);
    f[i] = 0.0;
  }

The resulting linear system A*u=f can now be solved using any linear-solver you prefer. Some solvers are provided in the linear_algebra submodule of Dune-DEC:

  Eigen::UmfPackLU<typename Matrix::Matrix> solver;

  DOFVector<double> u(gv, 0);
  solver.compute(A);
  u = solver.solve(f);

  msg("|A*u-f| = ", residuum(A, u, f));

Visualization

For the visualization, we write the DOFVector in a VTK-format, that can be plotted using ParaView:

  Dune::VTKWriter<GridView> writer(gv);
  writer.addVertexData(u, "u");
  writer.write("poisson");

That's it!

Clone repository
  • Home