diff --git a/python/dune/perftool/pdelab/__init__.py b/python/dune/perftool/pdelab/__init__.py index 929a58793efeb4f6f6692bb0711046e674acafc6..3a22422262ca80f232c5d45ca749d9a541b0b052 100644 --- a/python/dune/perftool/pdelab/__init__.py +++ b/python/dune/perftool/pdelab/__init__.py @@ -12,6 +12,7 @@ from dune.perftool.pdelab.argument import (pymbolic_apply_function, ) from dune.perftool.pdelab.basis import (pymbolic_basis, pymbolic_reference_gradient, + pymbolic_evaluate_gridfunction, ) from dune.perftool.pdelab.geometry import (component_iname, pymbolic_cell_volume, @@ -98,6 +99,9 @@ class PDELabInterface(object): def pymbolic_apply_function(self, element, restriction, index): return pymbolic_apply_function(self.visitor, element, restriction, index) + def pymbolic_evaluate_gridfunction(self, coeff, restriction, grad): + return pymbolic_evaluate_gridfunction(self.visitor, coeff, restriction, grad) + # # Tensor expression related generator functions # diff --git a/python/dune/perftool/pdelab/basis.py b/python/dune/perftool/pdelab/basis.py index 53917205e71c983e7036cffaf2d9c98aec30dc5a..b2593874aff3294224863a232f6ccb2728f6da89 100644 --- a/python/dune/perftool/pdelab/basis.py +++ b/python/dune/perftool/pdelab/basis.py @@ -6,6 +6,7 @@ from dune.perftool.generation import (backend, include_file, instruction, kernel_cached, + preamble, temporary_variable, ) from dune.perftool.options import (option_switch, @@ -23,6 +24,7 @@ from dune.perftool.pdelab.geometry import (component_iname, world_dimension, name_jacobian_inverse_transposed, to_cell_coordinates, + name_cell, ) from dune.perftool.pdelab.localoperator import (lop_template_ansatz_gfs, lop_template_test_gfs, @@ -227,3 +229,22 @@ def evaluate_coefficient_gradient(visitor, element, name, container, restriction forced_iname_deps=frozenset(get_backend("quad_inames")()).union(frozenset({dimindex})), forced_iname_deps_is_final=True, ) + + +@preamble +def bind_gridfunction_to_element(gf, restriction): + element = name_cell(restriction) + return "localFunction({}).bind({});".format(gf, element) + + +def pymbolic_evaluate_gridfunction(visitor, coeff, restriction, grad): + diffOrder = 1 if grad else 0 + + from dune.perftool.pdelab.localoperator import name_gridfunction_member + gridfunction = name_gridfunction_member(coeff, diffOrder) + + bind_gridfunction_to_element(gridfunction, restriction) + + # Foobar! + visitor.indices = None + return 1 diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py index 336062fced9212f64d2bae56f6ab67f64b4918aa..dffc7c88be19609985234ecddb4cdf1675ff60fa 100644 --- a/python/dune/perftool/pdelab/localoperator.py +++ b/python/dune/perftool/pdelab/localoperator.py @@ -157,24 +157,37 @@ def localoperator_basename(form_ident): return get_form_option("classname", form_ident) -def name_gridfunction_member(coeff): - name = "gridfunction_{}".format(coeff.count()) - define_gridfunction_member(name) +def name_gridfunction_member(coeff, diffOrder=0): + name = "gridfunction_coeff{}_diff{}".format(coeff.count(), diffOrder) + define_gridfunction_member(name, coeff, diffOrder) + return name + + +def name_gridfunction_constructor_argument(coeff): + _type = type_gridfunction_template_parameter(coeff) + name = "gridfunction_coeff{}_".format(coeff.count()) + constructor_parameter("const {}&".format(_type), name, classtag="operator") return name @class_member(classtag="operator") -def define_gridfunction_member(name): - _type = type_gridfunction_template_parameter(name) - param = "{}_".format(name) - constructor_parameter("const {}&".format(_type), param, classtag="operator") - initializer_list(name, [param], classtag="operator") - return "const {}& {};".format(_type, name) +def define_gridfunction_member(name, coeff, diffOrder): + _type = type_gridfunction_template_parameter(coeff) + param = name_gridfunction_constructor_argument(coeff) + if diffOrder > 0: + include_file("dune/pdelab/function/discretegridviewfunction.hh", filetag="operatorfile") + newtype = "Dune::PDELab::DiscreteGridViewFunction<typename {0}::GridFunctionSpace, typename {0}::Vector, {1}>".format(_type, diffOrder) + params = ["{}.gridFunctionSpace()".format(param), "{}.dofs()".format(param)] + initializer_list(name, params, classtag="operator") + return "{} {};".format(_type, name) + else: + initializer_list(name, [param], classtag="operator") + return "const {}& {};".format(_type, name) @template_parameter(classtag="operator") -def type_gridfunction_template_parameter(name): - return name.upper() +def type_gridfunction_template_parameter(coeff): + return "GRIDFUNCTION_COEFF{}".format(coeff.count()) def class_type_from_cache(classtag): diff --git a/python/dune/perftool/ufl/visitor.py b/python/dune/perftool/ufl/visitor.py index 6b4db02f317b561cb9af0e41446945d2c631c065..153f9713784b3d03d40053d493e34f50d7a645ff 100644 --- a/python/dune/perftool/ufl/visitor.py +++ b/python/dune/perftool/ufl/visitor.py @@ -127,13 +127,13 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker): return self.interface.pymbolic_basis(leaf_element, restriction, o.number()) def coefficient(self, o): + # Correct the restriction on boundary integrals + restriction = self.restriction + if self.measure == 'exterior_facet': + restriction = Restriction.NEGATIVE + # Do something different for trial function and coefficients from jacobian apply if o.count() == 0 or o.count() == 1: - # Correct the restriction on boundary integrals - restriction = self.restriction - if self.measure == 'exterior_facet': - restriction = Restriction.NEGATIVE - self.interface.initialize_function_spaces(o, self) index = None @@ -164,7 +164,7 @@ class UFL2LoopyVisitor(ModifiedTerminalTracker): # and exports it through a getter method 'getTime' return prim.Call(prim.Variable("getTime"), ()) else: - raise NotImplementedError("General Coefficients") + return self.interface.pymbolic_evaluate_gridfunction(o, restriction, self.reference_grad) # # Handlers for all indexing related stuff