diff --git a/src/amdis/localoperators/FirstOrderGradTestTrial.hpp b/src/amdis/localoperators/FirstOrderGradTestTrial.hpp index 6f1067e2de5e254cf7cc6a64c03ae1c155abb30d..c742f28fe60e715169fc7096b361929aa01852ce 100644 --- a/src/amdis/localoperators/FirstOrderGradTestTrial.hpp +++ b/src/amdis/localoperators/FirstOrderGradTestTrial.hpp @@ -14,6 +14,7 @@ namespace AMDiS namespace tag { struct gradtest_trial {}; + struct grad_test {}; } @@ -33,6 +34,14 @@ namespace AMDiS {} }; + + /// Create a first-order term with derivative on trial-function + template <class Expr, class... QuadratureArgs> + auto fot(Expr&& expr, tag::grad_test, QuadratureArgs&&... args) + { + return makeOperator(tag::gradtest_trial{}, FWD(expr), FWD(args)...); + } + /** @} **/ } // end namespace AMDiS diff --git a/src/amdis/localoperators/FirstOrderPartialTestTrial.hpp b/src/amdis/localoperators/FirstOrderPartialTestTrial.hpp index d094d03f43fca3cfe2e024dacbd59e245786fff5..246994760204e741f172d9083a2f67e65514e4fc 100644 --- a/src/amdis/localoperators/FirstOrderPartialTestTrial.hpp +++ b/src/amdis/localoperators/FirstOrderPartialTestTrial.hpp @@ -17,6 +17,11 @@ namespace AMDiS { std::size_t comp; }; + + struct partial_test + { + std::size_t comp; + }; } @@ -36,6 +41,14 @@ namespace AMDiS {} }; + + /// Create a first-order term with derivative on trial-function + template <class Expr, class... QuadratureArgs> + auto fot(Expr&& expr, tag::partial_test t, QuadratureArgs&&... args) + { + return makeOperator(tag::partialtest_trial{t.comp}, FWD(expr), FWD(args)...); + } + /** @} **/ } // end namespace AMDiS diff --git a/src/amdis/localoperators/FirstOrderTestGradTrial.hpp b/src/amdis/localoperators/FirstOrderTestGradTrial.hpp index 667fc203786c135c859438c982e2c023c815349d..fa161142757843a3cba123936d6f3a47e71becfc 100644 --- a/src/amdis/localoperators/FirstOrderTestGradTrial.hpp +++ b/src/amdis/localoperators/FirstOrderTestGradTrial.hpp @@ -17,6 +17,7 @@ namespace AMDiS namespace tag { struct test_gradtrial {}; + struct grad_trial {}; } @@ -97,6 +98,14 @@ namespace AMDiS } }; + + /// Create a first-order term with derivative on test-function + template <class Expr, class... QuadratureArgs> + auto fot(Expr&& expr, tag::grad_trial, QuadratureArgs&&... args) + { + return makeOperator(tag::test_gradtrial{}, FWD(expr), FWD(args)...); + } + /** @} **/ } // end namespace AMDiS diff --git a/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp b/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp index 2e40ac54042fa7e9852a8b40f8e30554585c6989..33628e2fe054a361d5bc594aec53eecbb684e521 100644 --- a/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp +++ b/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp @@ -20,6 +20,11 @@ namespace AMDiS { std::size_t comp; }; + + struct partial_trial + { + std::size_t comp; + }; } @@ -104,6 +109,14 @@ namespace AMDiS std::size_t comp_; }; + + /// Create a first-order term with derivative on trial-function + template <class Expr, class... QuadratureArgs> + auto fot(Expr&& expr, tag::partial_trial t, QuadratureArgs&&... args) + { + return makeOperator(tag::test_partialtrial{t.comp}, FWD(expr), FWD(args)...); + } + /** @} **/ } // end namespace AMDiS diff --git a/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp b/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp index 274f6352a203516ee5792322ae8e47daadff5b48..3e9416fb19bbffcb9ec9191e0df6ce893df2a0c0 100644 --- a/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp +++ b/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp @@ -230,6 +230,13 @@ namespace AMDiS } }; + /// Create a second-order term + template <class Expr, class... QuadratureArgs> + auto sot(Expr&& expr, QuadratureArgs&&... args) + { + return makeOperator(tag::gradtest_gradtrial{}, FWD(expr), FWD(args)...); + } + /** @} **/ } // end namespace AMDiS diff --git a/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp b/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp index 9a4e0234a7c1e3c18caa9b297636079ad2dede65..b0c78dd487676c840fbc0f535e1e4564e069c088 100644 --- a/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp +++ b/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp @@ -114,6 +114,14 @@ namespace AMDiS std::size_t compTrial_; }; + + /// Create a second-order term of partial derivatives + template <class Expr, class... QuadratureArgs> + auto sot_ij(Expr&& expr, std::size_t comp_test, std::size_t comp_trial, QuadratureArgs&&... args) + { + return makeOperator(tag::partialtest_partialtrial{comp_test, comp_trial}, FWD(expr), FWD(args)...); + } + /** @} **/ } // end namespace AMDiS diff --git a/src/amdis/localoperators/ZeroOrderTestTrial.hpp b/src/amdis/localoperators/ZeroOrderTestTrial.hpp index 59c88e928c4586cb69caa725249efd741785d8d7..127ef16d564f0b7c239e1e042ce5173ea1de49d4 100644 --- a/src/amdis/localoperators/ZeroOrderTestTrial.hpp +++ b/src/amdis/localoperators/ZeroOrderTestTrial.hpp @@ -51,7 +51,39 @@ namespace AMDiS getElementMatrixStandard(context, quad, rowNode, colNode, elementMatrix); } + template <class Context, class Node, class ElementVector> + void getElementVector(Context const& context, + Node const& node, + ElementVector& elementVector) + { + static_assert(Node::isLeaf, "Operator can be applied to Leaf-Nodes only"); + + auto const& quad = this->getQuadratureRule(context.type(), node); + auto const& localFE = node.finiteElement(); + std::size_t size = localFE.size(); + + NodeQuadCache<Node> cache(localFE.localBasis()); + + auto const& shapeValuesCache = cache.evaluateFunctionAtQP(context,quad); + for (std::size_t iq = 0; iq < quad.size(); ++iq) { + // Position of the current quadrature point in the reference element + decltype(auto) local = context.local(quad[iq].position()); + + // The multiplicative factor in the integral transformation formula + const auto factor = Super::coefficient(local) * context.integrationElement(quad[iq].position()) + * quad[iq].weight(); + + auto const& shapeValues = shapeValuesCache[iq]; + for (std::size_t i = 0; i < size; ++i) { + const auto local_i = node.localIndex(i); + elementVector[local_i] += factor * shapeValues[i]; + } + } + } + + protected: + template <class Context, class QuadratureRule, class RowNode, class ColNode, class ElementMatrix> void getElementMatrixStandard(Context const& context, QuadratureRule const& quad, @@ -138,6 +170,14 @@ namespace AMDiS } }; + + /// Create a zero-order term + template <class Expr, class... QuadratureArgs> + auto zot(Expr&& expr, QuadratureArgs&&... args) + { + return makeOperator(tag::test_trial{}, FWD(expr), FWD(args)...); + } + /** @} **/ } // end namespace AMDiS