30 template <
class CG,
class RN,
class CN,
class Quad,
class LocalFct,
class Mat>
31 void assemble(CG
const& contextGeo, RN
const& rowNode, CN
const& colNode,
32 Quad
const& quad, LocalFct
const& localFct, Mat& elementMatrix)
const
34 static_assert(static_size_v<typename LocalFct::Range> == 1,
35 "Expression must be of scalar type." );
37 const bool sameFE = std::is_same_v<FiniteElementType_t<RN>, FiniteElementType_t<CN>>;
38 const bool sameNode = rowNode.treeIndex() == colNode.treeIndex();
40 if (sameFE && sameNode)
41 getElementMatrixOptimized(contextGeo, quad, rowNode, colNode, localFct, elementMatrix);
43 getElementMatrixStandard(contextGeo, quad, rowNode, colNode, localFct, elementMatrix);
46 template <
class CG,
class Node,
class Quad,
class LocalFct,
class Vec>
47 void assemble(CG
const& contextGeo, Node
const& node,
48 Quad
const& quad, LocalFct
const& localFct, Vec& elementVector)
const
50 static_assert(static_size_v<typename LocalFct::Range> == 1,
51 "Expression must be of scalar type." );
52 static_assert(Dune::TypeTree::Concept::LeafTreeNode<Node>,
53 "Operator can be applied to Leaf-Nodes only");
55 std::size_t size = node.size();
57 for (
auto const& qp : quad) {
59 auto&& local = contextGeo.coordinateInElement(qp.position());
62 const auto factor = localFct(local) * contextGeo.integrationElement(qp.position()) * qp.weight();
64 auto const& shapeValues = node.localBasisValuesAt(local);
65 for (std::size_t i = 0; i < size; ++i) {
66 const auto local_i = node.localIndex(i);
67 elementVector[local_i] += factor * shapeValues[i];
74 template <
class CG,
class QR,
class RN,
class CN,
class LocalFct,
class Mat>
75 void getElementMatrixStandard(CG
const& contextGeo, QR
const& quad,
76 RN
const& rowNode, CN
const& colNode,
77 LocalFct
const& localFct, Mat& elementMatrix)
const
79 static_assert(Dune::TypeTree::Concept::LeafTreeNode<RN> && Dune::TypeTree::Concept::LeafTreeNode<CN>,
80 "Operator can be applied to Leaf-Nodes only.");
82 std::size_t rowSize = rowNode.size();
83 std::size_t colSize = colNode.size();
85 for (
auto const& qp : quad) {
87 auto&& local = contextGeo.coordinateInElement(qp.position());
90 const auto factor = localFct(local) * contextGeo.integrationElement(qp.position()) * qp.weight();
92 auto const& rowShapeValues = rowNode.localBasisValuesAt(local);
93 auto const& colShapeValues = colNode.localBasisValuesAt(local);
95 for (std::size_t i = 0; i < rowSize; ++i) {
96 const auto local_i = rowNode.localIndex(i);
97 const auto value = factor * rowShapeValues[i];
99 for (std::size_t j = 0; j < colSize; ++j) {
100 const auto local_j = colNode.localIndex(j);
101 elementMatrix[local_i][local_j] += value * colShapeValues[j];
108 template <
class CG,
class QR,
class RN,
class CN,
class LocalFct,
class Mat>
109 void getElementMatrixOptimized(CG
const& contextGeo, QR
const& quad,
110 RN
const& node, CN
const& ,
111 LocalFct
const& localFct, Mat& elementMatrix)
const
113 static_assert(Dune::TypeTree::Concept::LeafTreeNode<RN> && Dune::TypeTree::Concept::LeafTreeNode<CN>,
114 "Operator can be applied to Leaf-Nodes only.");
116 std::size_t size = node.size();
118 for (
auto const& qp : quad) {
120 auto&& local = contextGeo.coordinateInElement(qp.position());
123 const auto factor = localFct(local) * contextGeo.integrationElement(qp.position()) * qp.weight();
125 auto const& shapeValues = node.localBasisValuesAt(local);
127 for (std::size_t i = 0; i < size; ++i) {
128 const auto local_i = node.localIndex(i);
130 const auto value = factor * shapeValues[i];
131 elementMatrix[local_i][local_i] += value * shapeValues[i];
133 for (std::size_t j = i+1; j < size; ++j) {
134 const auto local_j = node.localIndex(j);
136 elementMatrix[local_i][local_j] += value * shapeValues[j];
137 elementMatrix[local_j][local_i] += value * shapeValues[j];