1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #pragma once #include #include #include #include #include namespace AMDiS { /// Base class for quadrature factories for localFunctions template class QuadratureFactory { protected: using QuadratureRule = Dune::QuadratureRule; public:  Praetorius, Simon committed Oct 18, 2018 20  virtual ~QuadratureFactory() = default;  21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 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  /// Bind the rule to a localFunction virtual void bind(LocalFunction const& localFct) {} /// Return the quadrature order of the coefficient relates to the localFunction virtual int order() const { return 0; } /// Construct a quadrature rule, based on the local geometry-type and the /// polynomial degree of the integrand function. virtual QuadratureRule const& rule(Dune::GeometryType const& type, int degree) const { using QuadratureRules = Dune::QuadratureRules; return QuadratureRules::rule(type, degree); } }; template using HasLocalFunctionOrder = decltype( order(std::declval()) ); /// \brief Factory for quadrature rule, that calculates the coefficient order from /// a localFunction passed to the bind method. template class QuadFactoryFromLocalFunction : public QuadratureFactory { using Concept = Dune::Std::is_detected; static_assert(Concept::value, "Polynomial order of GridFunction can not be extracted. Provide an explicit order parameter instead."); public: virtual void bind(LocalFunction const& localFct) final { order_ = Dune::Hybrid::ifElse(Concept{}, [&](auto id) { return AMDiS::order(id(localFct)); }, [] (auto) { return -1; }); } virtual int order() const final { return order_; } private: int order_ = -1; }; struct PreQuadFactoryFromLocalFunction {};  Praetorius, Simon committed Oct 05, 2018 72  inline auto makePreQuadratureFactory()  73 74 75 76 77 78 79 80 81 82 83 84 85 86 87  { return PreQuadFactoryFromLocalFunction{}; } /// Generator for \ref QuadFactoryFromLocalFunction. \relates QuadFactoryFromLocalFunction template auto makeQuadratureFactory(PreQuadFactoryFromLocalFunction const& /*pre*/) { return QuadFactoryFromLocalFunction{}; } template auto makeQuadratureFactoryPtr(PreQuadFactoryFromLocalFunction const& /*pre*/) { using Factory = QuadFactoryFromLocalFunction;  Praetorius, Simon committed Nov 18, 2018 88  return std::make_unique();  89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127  } /// \brief Factory for quadrature rule, that takes to order of the localFunction /// and a quadrature-type template class QuadFactoryFromOrder : public QuadratureFactory { using Super = QuadratureFactory; using QuadratureRule = typename Super::QuadratureRule; public: /// Constructor. Takes the order of the localCoefficient and a quadrature-type QuadFactoryFromOrder(int order, Dune::QuadratureType::Enum qt) : order_(order) , qt_(qt) {} virtual int order() const final { return order_; } virtual QuadratureRule const& rule(Dune::GeometryType const& type, int degree) const final { using QuadratureRules = Dune::QuadratureRules; return QuadratureRules::rule(type, degree, qt_); } private: int order_; Dune::QuadratureType::Enum qt_; }; struct PreQuadFactoryFromOrder { int order; Dune::QuadratureType::Enum qt; };  Praetorius, Simon committed Oct 05, 2018 128  inline auto makePreQuadratureFactory(int order, Dune::QuadratureType::Enum qt = Dune::QuadratureType::GaussLegendre)  129 130 131 132 133 134 135 136 137 138 139 140 141 142 143  { return PreQuadFactoryFromOrder{order, qt}; } /// Generator for \ref QuadFactoryFromOrder. \relates QuadFactoryFromOrder template auto makeQuadratureFactory(PreQuadFactoryFromOrder const& pre) { return QuadFactoryFromOrder{pre.order, pre.qt}; } template auto makeQuadratureFactoryPtr(PreQuadFactoryFromOrder const& pre) { using Factory = QuadFactoryFromOrder;  Praetorius, Simon committed Nov 18, 2018 144  return std::make_unique(pre.order, pre.qt);  145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193  } /// \brief Factory for quadrature rule, that is based on an existing rule template class QuadFactoryFromRule : public QuadratureFactory { using Super = QuadratureFactory; using QuadratureRule = typename Super::QuadratureRule; public: QuadFactoryFromRule(QuadratureRule const& rule) : rule_(rule) {} virtual QuadratureRule const& rule(Dune::GeometryType const& /*type*/, int /*degree*/) const final { return rule_; } private: QuadratureRule const& rule_; }; template struct PreQuadFactoryFromRule { QuadRule const& rule; }; template auto makePreQuadratureFactory(Dune::QuadratureRule const& rule) { return PreQuadFactoryFromRule>{rule}; } /// Generator for \ref QuadFactoryFromRule. \relates QuadFactoryFromRule template auto makeQuadratureFactory(PreQuadFactoryFromRule const& pre) { return QuadFactoryFromRule{pre.rule}; } template auto makeQuadratureFactoryPtr(PreQuadFactoryFromRule const& pre) { using Factory = QuadFactoryFromRule;  Praetorius, Simon committed Nov 18, 2018 194  return std::make_unique(pre.rule);  195 196 197  } } // end namespace AMDiS