Assembler.hpp 2.65 KB
Newer Older
1 2 3 4
#pragma once

namespace AMDiS
{
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  template <class ElementAssembler, class IntersectionAssembler, class BoundaryAssembler>
  struct AssemblerTriple
  {
    ElementAssembler elementAssembler;
    IntersectionAssembler intersectionAssembler;
    BoundaryAssembler boundaryAssembler;
  };

  template <class EA, class IA, class BA>
  AssemblerTriple<EA, IA, BA> makeAssemblerTriple(EA const& ea, IA const& ia, BA const& ba)
  {
    return {ea, ia, ba};
  }


  template <class GridView, class Element, class Operators, class EA, class IA, class BA>
21 22 23 24
  void assembleOperators(
      GridView const& gridView,
      Element const& element,
      Operators& operators,
25
      AssemblerTriple<EA,IA,BA> const& assemblerTriple)
26
  {
27
    // assemble element operators
28
    assemblerTriple.elementAssembler(element, operators.onElement());
29 30

    // assemble intersection operators
Praetorius, Simon's avatar
Praetorius, Simon committed
31 32
    if (!operators.onIntersection().empty()
        || (!operators.onBoundary().empty() && element.hasBoundaryIntersections()))
33 34 35
    {
      for (auto const& intersection : intersections(gridView, element)) {
        if (intersection.boundary())
36
          assemblerTriple.boundaryAssembler(intersection, operators.onBoundary());
37
        else
38
          assemblerTriple.intersectionAssembler(intersection, operators.onIntersection());
39 40 41
      }
    }
  }
42

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84

  template <class Node, class ElementVector>
  auto makeVectorAssembler(Node const& node, ElementVector& elementVector)
  {
    return makeAssemblerTriple(
      [&](auto const& element, auto& operators) {
        for (auto op : operators)
          op->assemble(element, node, elementVector);
      },
      [&](auto const& is, auto& operators) {
        for (auto op : operators)
          op->assemble(is, node, elementVector);
      },
      [&](auto const& bis, auto& operators) {
        for (auto data : operators) {
          if (data.bc.onBoundary(bis))
            data.op->assemble(bis, node, elementVector);
        }
      });
  }


  template <class RowNode, class ColNode, class ElementMatrix>
  auto makeMatrixAssembler(RowNode const& rowNode, ColNode const& colNode, ElementMatrix& elementMatrix)
  {
    return makeAssemblerTriple(
      [&](auto const& element, auto& operators) {
        for (auto op : operators)
          op->assemble(element, rowNode, colNode, elementMatrix);
      },
      [&](auto const& is, auto& operators) {
        for (auto op : operators)
          op->assemble(is, rowNode, colNode, elementMatrix);
      },
      [&](auto const& bis, auto& operators) {
        for (auto data : operators) {
          if (data.bc.onBoundary(bis))
            data.op->assemble(bis, rowNode, colNode, elementMatrix);
        }
      });
  }

85
} // end namespace AMDiS