diff --git a/python/dune/perftool/pdelab/driver/constraints.py b/python/dune/perftool/pdelab/driver/constraints.py index ddb880ee2d0d667547d3883a137dc886d244a823..dc65354a08452b783a377f53f401e8b7f445c766 100644 --- a/python/dune/perftool/pdelab/driver/constraints.py +++ b/python/dune/perftool/pdelab/driver/constraints.py @@ -1,4 +1,5 @@ -from dune.perftool.generation import (global_context, +from dune.perftool.generation import (get_counted_variable, + global_context, include_file, preamble, ) @@ -52,12 +53,10 @@ def assemble_constraints(name): def name_bctype_function(element, is_dirichlet): - if isinstance(element, (VectorElement, TensorElement)): - subel = element.sub_elements()[0] - child = name_bctype_function(subel, is_dirichlet[:subel.value_size()]) - name = "{}_pow{}bctype".format(child, element.num_sub_elements()) - define_power_bctype_function(element, name, child) - return name + # Note: Previously, there was a separate code branch for VectorElement here, + # which was implemented through PDELabs Power constraints concept. + # However this completely fails if you have different constraints for + # the children of a VectorElement. We therefore omit this branch completely. if isinstance(element, MixedElement): k = 0 childs = [] @@ -69,7 +68,7 @@ def name_bctype_function(element, is_dirichlet): return name else: assert isinstance(element, (FiniteElement, TensorProductElement)) - name = "{}_bctype".format(FEM_name_mangling(element).lower()) + name = get_counted_variable("bctype") define_bctype_function(element, is_dirichlet[0], name) return name @@ -85,12 +84,6 @@ def define_bctype_function(element, is_dirichlet, name): ) -@preamble(section="constraints") -def define_power_bctype_function(element, name, subgfs): - include_file('dune/pdelab/constraints/common/constraintsparameters.hh', filetag='driver') - return "Dune::PDELab::PowerConstraintsParameters<decltype({}), {}> {}({});".format(subgfs, element.num_sub_elements(), name, subgfs) - - @preamble(section="constraints") def define_composite_bctype_function(element, is_dirichlet, name, subgfs): include_file('dune/pdelab/constraints/common/constraintsparameters.hh', filetag='driver') @@ -115,7 +108,7 @@ def define_intersection_lambda(name, func): return "auto {} = [&](const auto& x){{ return {}; }};".format(name, float(func)) elif isinstance(func, Expr): from dune.perftool.pdelab.driver.visitor import ufl_to_code - return "auto {} = [&](const auto& x){{ return {}; }};".format(name, ufl_to_code(func)) + return "auto {} = [&](const auto& is, const auto& xl){{ {} }};".format(name, ufl_to_code(func)) raise ValueError("Expression not understood") diff --git a/python/dune/perftool/pdelab/driver/interpolate.py b/python/dune/perftool/pdelab/driver/interpolate.py index 75846a1f57bead0d7ca87c0014a3e8715c2836d6..36ff21d9c7c47440569fc55cc76eb39b8fbb05a3 100644 --- a/python/dune/perftool/pdelab/driver/interpolate.py +++ b/python/dune/perftool/pdelab/driver/interpolate.py @@ -95,10 +95,7 @@ def define_boundary_lambda(name, boundary): if isinstance(boundary, (int, float)): return "auto {} = [&](const auto& x){{ return {}; }};".format(name, float(boundary)) elif isinstance(boundary, Expr): - from dune.perftool.loopy.target import type_floatingpoint from dune.perftool.pdelab.driver.visitor import ufl_to_code - return "auto {} = [&](const auto& x){{ return ({}){}; }};".format(name, - type_floatingpoint(), - ufl_to_code(boundary)) + return "auto {} = [&](const auto& is, const auto& xl){{ {}; }};".format(name, ufl_to_code(boundary)) else: raise NotImplementedError("What is this?") diff --git a/python/dune/perftool/pdelab/driver/visitor.py b/python/dune/perftool/pdelab/driver/visitor.py index da7c10ddb82273bef3b904a02295e3fe6e232eb5..c126e40d79a02b32501390ecf76f6c3bded07f72 100644 --- a/python/dune/perftool/pdelab/driver/visitor.py +++ b/python/dune/perftool/pdelab/driver/visitor.py @@ -4,11 +4,6 @@ from dune.perftool.ufl.visitor import UFL2LoopyVisitor import pymbolic.primitives as prim -@preamble(section="init") -def driver_using_statement(what): - return "using {};".format(what) - - @preamble(section="gridoperator") def set_lop_to_starting_time(): from dune.perftool.pdelab.driver import get_form_ident @@ -23,17 +18,24 @@ class DriverUFL2PymbolicVisitor(UFL2LoopyVisitor): UFL2LoopyVisitor.__init__(self, PDELabInterface(), "exterior_facet", {}) def __call__(self, expr): - return self._call(expr, False) + self.preambles = [] + ret = self._call(expr, False) + return set(self.preambles), ret + + def facet_normal(self, o): + self.preambles.append("auto n=is.unitOuterNormal(xl);") + return prim.Variable("n") def spatial_coordinate(self, o): + self.preambles.append("auto x=is.geometry().global(xl);") return prim.Variable("x") def max_value(self, o): - driver_using_statement("std::max") + self.preambles.append("using std::max;") return UFL2LoopyVisitor.max_value(self, o) def min_value(self, o): - driver_using_statement("std::min") + self.preambles.append("using std::min;") return UFL2LoopyVisitor.min_value(self, o) def coefficient(self, o): @@ -55,5 +57,5 @@ def ufl_to_code(expr, boundary=True): visitor = DriverUFL2PymbolicVisitor() from pymbolic.mapper.c_code import CCodeMapper ccm = CCodeMapper() - vis = visitor(expr) - return ccm(vis) + preambles, vis_expr = visitor(expr) + return "{} return {};".format("".join(preambles), ccm(vis_expr))