Skip to content
Snippets Groups Projects

Add a Mapping of a Geometry

Merged Simon Praetorius requested to merge feature/mapped-geometry2 into master

Summary

Essentially, a geometry is a local functions that is differentiable and invertible, plus some extra utility functions for volume and integration element. It would be nice to have a way to chain these "functions", or to combine it with a classical differentiable function.

This MR adds a transformation/mapping of a geometry.

Examples

In the following three examples, functions defined on different domains with different interpretations of derivatives are shown.

  1. In Example 1, a function that can be evaluated in global coordinates with a derivative w.r.t. global coordinates is used. This requires that we map first from the reference element to the grid element and also requires that the jacobian is transformed from global coordinates to local coordinates
  2. In Example 2, the function is defined purely local, in terms of a local basis and a linear-combination of the basis functions. Thus, the evaluation is in local coordinates and the derivatives are already w.r.t. local coordinates. No additional transformation into a real element is required and we can use the reference-element geometry instead.
  3. The last example, Example 3, is in between the first two examples. Thereby, the function can be evaluated in local coordinates, but the derivatives are defined w.r.t. global coordinates. Thus, we need to transform only the derivative, using a special wrapper around the reference-element geometry, returning the jacobianTransposed() from the real geometry.

Example 1

An analytic function for the parametrization:

// construct a base grid e.g. with piecewise flat elements
YaspGrid<2> grid({1.0,1.0}, {10,10});

using Domain = FieldVector<double,2>;
using Range = FieldVector<double,3>;

auto sig = Functions::SignatureTag<Range(Domain)>{};
auto f = Functions::makeDifferentiableFunctionFromCallables(sig, 
  [](const Domain& x) -> FieldVector<double,3> {
    return {x[0], x[1], std::sin(x[0] * x[1])};
  },
  [](const Domain& x) -> FieldMatrix<double,3,2> {
    return {
      {1.0, 0.0},
      {0.0, 1.0},
      {x[1] * std::cos(x[0] * x[1]), x[0] * std::cos(x[0] * x[1])}
    };
  });

for (const auto& e : elements(grid.leafGridView()))
{
  // construct the mapped geometry
  MappedGeometry geometry{f, e.geometry()};
}

Examples 2

A discrete function build from dune-localfunction local finite-element basis functions:

template <class LocalBasis, class Coefficients>
class LocalFunction
{
  // implementation of a discrete function based on linear-combination of basis functions
};

using LocalFiniteElement = LagrangeCubeLocalFiniteElement<double,double,2,order>;
using Range = FieldVector<double,3>;

// construct a base grid e.g. with piecewise flat elements
YaspGrid<2> grid({1.0,1.0}, {10,10});
LocalFiniteElement localFE{};

for (const auto& e : elements(grid.leafGridView()))
{
  auto X = [geo=e.geometry()](const auto& local) -> Range
  {
    auto x = geo.global(local);
    return {x[0], x[1], std::sin(x[0] * x[1])};
  };

  std::vector<Range> vertices;
  localFE.localInterpolation().interpolate(X, vertices);

  // construct the mapped geometry
  LocalFunction lf{localFE.localBasis(), vertices};
  MappedGeometry geometry{lf, ReferenceElementGeometry{referenceElement(e)}};
  // or
  // auto refElem = referenceElement(e);
  // MappendGeometry geometry{lf, refElem.template geometry<0>(0)};
}

Example 3

In case you get a local function created from a grid-function with a derivative in global coordinates, but the argument is already transformed by a geometry, you can use the additional wrapper LocalDerivativeGeometry:

// construct a base grid e.g. with piecewise flat elements
YaspGrid<2> grid({1.0,1.0}, {10,10});

using Domain = FieldVector<double,2>;
using Range = FieldVector<double,3>;

auto sig = Functions::SignatureTag<Range(Domain)>{};
auto f = Functions::makeDifferentiableFunctionFromCallables(sig, 
  [](const Domain& x) -> FieldVector<double,3> {
    return {x[0], x[1], std::sin(x[0] * x[1])};
  },
  [](const Domain& x) -> FieldMatrix<double,3,2> {
    return {
      {1.0, 0.0},
      {0.0, 1.0},
      {x[1] * std::cos(x[0] * x[1]), x[0] * std::cos(x[0] * x[1])}
    };
  });

// create a differentiable analytic grid function
auto fGridFunction = Functions::makeAnalyticGridViewFunction(f, grid.leafGridView());

// build the corresponding local function
auto fLocalFunction = localFunction(fGridFunction);

for (const auto& e : elements(grid.leafGridView()))
{
  // bind the local function to the grid element
  fLocalFunction.bind(e);

  // construct the mapped geometry
  MappedGeometry geometry{fLocalFunction, LocalDerivativeGeometry{e.geometry()}};

  // unbind the local function from the element
  fLocalFunction.unbind();
}
Edited by Simon Praetorius

Merge request reports

Merge request pipeline passed for ab56bf6b

Approval is optional
Test summary results are being parsed

Merged by Simon PraetoriusSimon Praetorius 11 months ago (Mar 6, 2024 8:09pm UTC)

Merge details

  • Changes merged into master with d45c81e1.
  • Deleted the source branch.

Pipeline passed for d45c81e1 on master

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Simon Praetorius changed the description

    changed the description

  • Has anyone an opinion about this MR? Before I continue with the implementation, I want to know whether you like the idea.

  • Simon Praetorius marked this merge request as draft

    marked this merge request as draft

  • Simon Praetorius changed title from WIP: Add a Mapping of a Geometry to Draft: Add a Mapping of a Geometry

    changed title from WIP: Add a Mapping of a Geometry to Draft: Add a Mapping of a Geometry

  • Simon Praetorius changed the description

    changed the description

  • added feature label

  • Simon Praetorius added 69 commits

    added 69 commits

    • 9051ff18...39fc5053 - 63 commits from branch master
    • b87725f0 - Add geometry mapped by an element-function
    • 14f67280 - Some tweaking of the MappingGeometry, removing unused fields and types and added some documentation
    • c97cb335 - Improve the documentation
    • 347b14b4 - Remove necessity to bind the derivative to an element
    • 5fc861af - Restructure MappedGeometry to implement a mapping of a geometry, and add a ChainedGeometry
    • f23bdbe9 - Modify tests and change the order of the arguments

    Compare with previous version

  • added 1 commit

    • 5c268561 - Implement jacobian() and jacobinaInverse() methods

    Compare with previous version

  • added 1 commit

    Compare with previous version

  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Please register or sign in to reply
    Loading