From 5ef2b1de08be8288d21417eea71baac240ef5644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20He=C3=9F?= <rene.hess@iwr.uni-heidelberg.de> Date: Mon, 26 Aug 2019 14:38:03 +0200 Subject: [PATCH] [skip ci] Big code cleanup and bugfix --- python/dune/codegen/pdelab/driver/error.py | 55 +--- .../codegen/pdelab/driver/instationary.py | 5 +- .../dune/codegen/pdelab/driver/interpolate.py | 295 +++++++++--------- 3 files changed, 153 insertions(+), 202 deletions(-) diff --git a/python/dune/codegen/pdelab/driver/error.py b/python/dune/codegen/pdelab/driver/error.py index c9f3a6b8..523caeec 100644 --- a/python/dune/codegen/pdelab/driver/error.py +++ b/python/dune/codegen/pdelab/driver/error.py @@ -16,8 +16,8 @@ from dune.codegen.pdelab.driver.gridfunctionspace import (main_type_trial_gfs, main_type_subgfs, ) from dune.codegen.pdelab.driver.interpolate import (interpolate_vector, - main_name_boundary_grid_function, - main_type_boundary_grid_function, + main_name_grid_function, + main_type_grid_function, ) from dune.codegen.pdelab.driver.solve import (define_vector, dune_solve, @@ -38,46 +38,6 @@ def name_test_fail_variable(): return name -@preamble(section="error", kernel="main") -def main_typedef_exact_solution_grid_function(name, treepath): - # palpo TODO - solution_type = main_type_boundary_grid_function() - # solution_type = "BoundaryGridFunction" - if len(treepath) > 0: - solution_type = "Dune::TypeTree::Child<{}, {}>;".format(solution_type, ", ".join(str(t) for t in treepath)) - return "using {} = {};".format(name, solution_type) - - -def main_type_exact_solution_grid_function(treepath): - name = "ExactSolution" - if len(treepath) > 0: - name = "{}_{}".format(name, "_".join(str(t) for t in treepath)) - main_typedef_exact_solution_grid_function(name, treepath) - return name - - -@preamble(section="error", kernel="main") -def main_define_exact_solution_grid_function(name, treepath): - element = get_trial_element() - func = preprocess_leaf_data(element, "exact_solution") - # palpo TODO - # boundary_gf = "boundaryGridFunction" - boundary_gf = main_name_boundary_grid_function(element, func) - if len(treepath) == 0: - return "auto {} = *{};".format(name, boundary_gf) - else: - indices = ["Dune::Indices::_{}".format(str(t)) for t in treepath] - return "auto {} = child(*{}, {});".format(name, boundary_gf, ", ".join(i for i in indices)) - - -def main_name_exact_solution_grid_function(treepath): - name = "exactSolution" - if len(treepath) > 0: - name = "{}_{}".format(name, "_".join(str(t) for t in treepath)) - main_define_exact_solution_grid_function(name, treepath) - return name - - def type_discrete_grid_function(treepath): name = "DiscreteGridFunction_{}".format("_".join(str(t) for t in treepath)) return name @@ -109,14 +69,7 @@ def name_discrete_grid_function(gfs, vector_name, treepath): @preamble(section="error", kernel="main") def typedef_difference_squared_adapter(name, treepath): - # Grid function representing exact solution - # element = get_trial_element() - # func = preprocess_leaf_data(element, "exact_solution") - # if isinstance(element, MixedElement): - # index = treepath_to_index(element, treepath) - # func = (func[index],) - # element = element.extract_component(index)[1] - bgf_type = main_type_exact_solution_grid_function(treepath) + bgf_type = main_type_grid_function("exact_solution", treepath) # Discrete grid function (numerical solution) gfs = main_name_trial_subgfs(treepath) @@ -136,7 +89,7 @@ def type_difference_squared_adapter(treepath): @preamble(section="error", kernel="main") def define_difference_squared_adapter(name, treepath): t = type_difference_squared_adapter(treepath) - sol = main_name_exact_solution_grid_function(treepath) + sol = main_name_grid_function("exact_solution", treepath) vector = main_name_vector(get_form_ident()) gfs = main_name_trial_subgfs(treepath) dgf = name_discrete_grid_function(gfs, vector, treepath) diff --git a/python/dune/codegen/pdelab/driver/instationary.py b/python/dune/codegen/pdelab/driver/instationary.py index 3f203c86..c8edb474 100644 --- a/python/dune/codegen/pdelab/driver/instationary.py +++ b/python/dune/codegen/pdelab/driver/instationary.py @@ -19,7 +19,7 @@ from dune.codegen.pdelab.driver.constraints import (has_dirichlet_constraints, name_constraintscontainer, ) from dune.codegen.pdelab.driver.interpolate import (interpolate_dirichlet_data, - name_boundary_grid_function, + name_grid_function_root, ) from dune.codegen.pdelab.driver.solve import (print_matrix, print_residual, @@ -79,8 +79,7 @@ def time_loop(): else: osm = name_onestepmethod() if has_dirichlet_constraints(is_dirichlet): - dirichlet = preprocess_leaf_data(element, "interpolate_expression") - boundary = name_boundary_grid_function(element, dirichlet) + boundary = name_boundary_grid_function_root("interpolate_expression") apply_call = "{}.apply(time, dt, {}, {}, {}new);".format(osm, vector, boundary, vector) else: apply_call = "{}.apply(time, dt, {}, {}new);".format(osm, vector, vector) diff --git a/python/dune/codegen/pdelab/driver/interpolate.py b/python/dune/codegen/pdelab/driver/interpolate.py index 40fddda5..6a52f485 100644 --- a/python/dune/codegen/pdelab/driver/interpolate.py +++ b/python/dune/codegen/pdelab/driver/interpolate.py @@ -21,109 +21,155 @@ from dune.codegen.pdelab.driver.gridfunctionspace import (name_trial_gfs, from ufl import FiniteElement, MixedElement, TensorElement, VectorElement, TensorProductElement +@preamble(section="vector", kernel="driver_block") +def interpolate_vector(func, gfs, name): + return "Dune::PDELab::interpolate(*{}, *{}, *{});".format(func, + gfs, + name, + ) + + def interpolate_dirichlet_data(name): element = get_trial_element() func = preprocess_leaf_data(element, "interpolate_expression", applyZeroDefault=False) if func is not None: - bf = name_boundary_grid_function(element, func) + bf = name_grid_function_root("interpolate_expression") gfs = name_trial_gfs() interpolate_vector(bf, gfs, name) -@preamble(section="vector", kernel="driver_block") -def interpolate_vector(func, gfs, name): - return "Dune::PDELab::interpolate(*{}, *{}, *{});".format(func, - gfs, - name, - ) +def _grid_function_root_type(identifier): + name_dict = {"exact_solution": "ExactSolution", + "interpolate_expression": "BoundaryGridFunction"} + return name_dict[identifier] + + +def _grid_function_root_name(identifier): + name_dict = {"exact_solution": "exactSolution", + "interpolate_expression": "boundaryGridFunction"} + return name_dict[identifier] + + +def _get_grid_function_method_name(identifier): + name_dict = {"exact_solution": "getExactSolution", + "interpolate_expression": "getBoundaryGridFunction"} + return name_dict[identifier] @class_member(classtag="driver_block") -def typedef_composite_boundary_grid_function(name, children): +def typedef_composite_grid_function(name, children): templates = ','.join('std::decay_t<decltype(*{})>'.format(c) for c in children) return "using {} = Dune::PDELab::CompositeGridFunction<{}>;".format(name, templates) -def type_composite_boundary_grid_function(children, root): +def type_composite_grid_function(identifier, children, root): if root: - name = "BoundaryGridFunction" + name = _grid_function_root_type(identifier) else: name = "CompositeGridFunction_{}".format('_'.join(c for c in children)) - typedef_composite_boundary_grid_function(name, children) + typedef_composite_grid_function(name, children) return name @class_member(classtag="driver_block") -def declare_composite_boundary_grid_function(name, children, root): - composite_gfs_type = type_composite_boundary_grid_function(children, root) +def declare_composite_grid_function(identifier, name, children, root): + composite_gfs_type = type_composite_grid_function(identifier, children, root) return "std::shared_ptr<{}> {};".format(composite_gfs_type, name) @preamble(section="vector", kernel="driver_block") -def define_composite_boundary_grid_function(name, children, root=False): - declare_composite_boundary_grid_function(name, children, root) - composite_gfs_type = type_composite_boundary_grid_function(children, root) +def define_composite_grid_function(identifier, name, children, root=True): + declare_composite_grid_function(identifier, name, children, root) + composite_gfs_type = type_composite_grid_function(identifier, children, root) return "{} = std::make_shared<{}>({});".format(name, composite_gfs_type, ', '.join('*{}'.format(c) for c in children)) -def _is_local(func): - # palpo TODO - return True - # return False - # assert isinstance(func, tuple) - # if len(func) == 2: - # return True - # else: - # try: - # assert len(func) == 1 - # except: - # from pudb import set_trace; set_trace() - # return False +def function_lambda(func): + assert isinstance(func, tuple) + func = func[0] + if func is None: + func = 0.0 + + if isinstance(func, (int, float)): + return "[&](const auto& is, const auto& xl){{ return {}; }}".format(float(func)) + else: + from ufl.classes import Expr + assert isinstance(func, Expr) + from dune.codegen.pdelab.driver.visitor import ufl_to_code + return "[&](const auto& is, const auto& xl){{ {}; }}".format(ufl_to_code(func)) @class_member(classtag="driver_block") -def typedef_boundary_grid_function(name, local): +def typedef_function(name): + range_type = type_range() + leafview_type = type_leafview() + entity = "typename {}::template Codim<0>::Entity".format(leafview_type) + coordinate = "typename {}::template Codim<0>::Entity::Geometry::LocalCoordinate".format(leafview_type) + return "using {} = std::function<{}({}, {})>;".format(name, range_type, entity, coordinate) + + +def type_function(): + name = "FunctionExpression" + typedef_function(name) + return name + + +@class_member(classtag="driver_block") +def declare_function(name): + function_type = type_function() + return "std::shared_ptr<{}> {};".format(function_type, name) + + +@preamble(section="vector", kernel="driver_block") +def define_function(name, func): + declare_function(name) + function_type = type_function() + fct_lambda = function_lambda(func) + return "{} = std::make_shared<{}> ({});".format(name, function_type, fct_lambda) + + +@cached +def name_function(func): + name = get_counted_variable("functionExpression") + define_function(name, func) + return name + + +@class_member(classtag="driver_block") +def typedef_grid_function(name): leafview_type = type_leafview() range_type = type_range() - boundary_function_type = type_boundary_function(local) - # palpo TODO: 1 in the format below! + function_type = type_function() return "using {} = Dune::PDELab::LocalCallableToGridFunctionAdapter<{}, {}, {}, {}>;".format(name, leafview_type, range_type, 1, - boundary_function_type) + function_type) -def type_boundary_grid_function(local, root): - # TODO: remove local stuff - # if local: - # name = "BoundaryGridFunctionLocal" - # else: - # name = "BoundaryGridFunctionGlobal" +def type_grid_function(identifier, root): + name = "GridFunctionLeaf" if root: - name = "BoundaryGridFunction" - else: - name = "BoundaryGridFunctionLeaf" - typedef_boundary_grid_function(name, local) + name = _grid_function_root_type(identifier) + typedef_grid_function(name) return name @class_member(classtag="driver_block") -def declare_boundary_grid_function(name, local, root): - bgf_type = type_boundary_grid_function(local, root) - return "std::shared_ptr<{}> {};".format(bgf_type, name) +def declare_grid_function(identifier, name, root): + grid_function_type = type_grid_function(identifier, root) + return "std::shared_ptr<{}> {};".format(grid_function_type, name) @preamble(section="vector", kernel="driver_block") -def define_boundary_grid_function(name, func, root=False): - local = _is_local(func) - declare_boundary_grid_function(name, local, root) +def define_grid_function(identifier, name, func, root=True): + declare_grid_function(identifier, name, root) gv = name_leafview() - boundary_function = name_boundary_function(func, local) - bgf_type = type_boundary_grid_function(local, root) + function_name = name_function(func) + grid_function_type = type_grid_function(identifier, root) include_file('dune/pdelab/function/callableadapter.hh', filetag='driver') if is_stationary(): - return "{} = std::make_shared<{}>({}, *{});".format(name, bgf_type, gv, boundary_function) + return "{} = std::make_shared<{}>({}, *{});".format(name, grid_function_type, gv, function_name) else: # palpo TODO assert False @@ -136,134 +182,87 @@ def define_boundary_grid_function(name, func, root=False): ) -@cached -def name_boundary_grid_function(element, func, root=True): + +def name_grid_function(identifier, element, func, root=True): assert isinstance(func, tuple) if isinstance(element, MixedElement): k = 0 childs = [] for subel in element.sub_elements(): - childs.append(name_boundary_grid_function(subel, func[k:k + subel.value_size()], root=False)) + childs.append(name_grid_function(identifier, subel, func[k:k + subel.value_size()], root=False)) k = k + subel.value_size() name = "_".join(childs) if len(childs) == 1: name = "{}_dummy".format(name) if root: - name = "boundary_grid_function" - define_composite_boundary_grid_function(name, tuple(childs), root=root) + name = identifier + define_composite_grid_function(identifier, name, tuple(childs), root=root) else: assert isinstance(element, (FiniteElement, TensorProductElement)) - name = get_counted_variable("boundary_grid_function") + name = get_counted_variable(identifier) if root: - name = "boundary_grid_function" - define_boundary_grid_function(name, func, root=root) - if root: - print("palpo 1 element: {}".format(element)) - driver_block_get_boundarygridfunction(element, func, name=name) + name = identifier + define_grid_function(identifier, name, func, root=root) return name -def boundary_lambda(func, local): - # palpo TODO - assert isinstance(func, tuple) - func = func[0] - if func is None: - func = 0.0 - - if isinstance(func, (int, float)): - return "[&](const auto& is, const auto& x){{ return {}; }}".format(float(func)) - else: - from ufl.classes import Expr - assert isinstance(func, Expr) - from dune.codegen.pdelab.driver.visitor import ufl_to_code - return "[&](const auto& is, const auto& xl){{ {}; }}".format(ufl_to_code(func)) - - -@class_member(classtag="driver_block") -def typedef_boundary_function(name, local): - range_type = type_range() - leafview_type = type_leafview() - if not local: - coordinate = "typename {}::template Codim<0>::Entity::Geometry::GlobalCoordinate".format(leafview_type) - return "using {} = std::function<{}({})>;".format(name, range_type, coordinate) - else: - entity = "typename {}::template Codim<0>::Entity".format(leafview_type) - coordinate = "typename {}::template Codim<0>::Entity::Geometry::LocalCoordinate".format(leafview_type) - return "using {} = std::function<{}({}, {})>;".format(name, range_type, entity, coordinate) - - -def type_boundary_function(local): - name = "BoundaryFunction" - if not local: - name = name + "Global" - else: - name = name + "Local" - typedef_boundary_function(name, local) +def name_grid_function_root(identifier): + element = get_trial_element() + func = preprocess_leaf_data(element, identifier) + name = name_grid_function(identifier, element, func, root=True) return name -@class_member(classtag="driver_block") -def declare_boundary_function(name, local): - bf_type = type_boundary_function(local) - return "std::shared_ptr<{}> {};".format(bf_type, name) - - -@preamble(section="vector", kernel="driver_block") -def define_boundary_function(name, func, local): - declare_boundary_function(name, local) - bf_type = type_boundary_function(local) - bf_lambda = boundary_lambda(func, local) - return "{} = std::make_shared<{}> ({});".format(name, bf_type, bf_lambda) - - -@cached -def name_boundary_function(func, local): - name = get_counted_variable("boundary_function") - define_boundary_function(name, func, local) - return name +@preamble(section="postprocessing", kernel="main") +def main_typedef_grid_function(name, identifier, treepath): + if len(treepath) == 0: + driver_block_type = type_driver_block() + gf_type = _grid_function_root_type(identifier) + type_name = "{}::{}".format(driver_block_type, gf_type) + else: + root_type = main_type_grid_function(identifier, ()) + type_name = "Dune::TypeTree::Child<{}, {}>;".format(root_type, ", ".join(str(t) for t in treepath)) + return "using {} = {};".format(name, type_name) -@preamble(section="postprocessing", kernel="main") -def main_typedef_boundary_grid_function(name): - driver_block_type = type_driver_block() - # palpo TODO - local = True - # bgf_type = type_boundary_grid_function(local, True) - bgf_type = "BoundaryGridFunction" - print("palpo name: {}".format(name)) - return "using {} = {}::{};".format(name, driver_block_type, bgf_type) - - -def main_type_boundary_grid_function(): - name = "BoundaryGridFunction" - main_typedef_boundary_grid_function(name) +def main_type_grid_function(identifier, treepath): + name = _grid_function_root_type(identifier) + if len(treepath) > 0: + name = "{}_{}".format(name, "_".join(str(t) for t in treepath)) + main_typedef_grid_function(name, identifier, treepath) return name @class_member(classtag="driver_block") -def driver_block_get_boundarygridfunction(element, func, name=None): +def driver_block_get_grid_function(identifier, name=None): + assert identifier in ["exact_solution", "interpolate_expression"] if not name: - name = name_boundary_grid_function(element, func) - # bgf_type = type_boundary_grid_function(True, True) - bgf_type = "BoundaryGridFunction" - return ["std::shared_ptr<{}> getBoundaryGridFunction(){{".format(bgf_type), + name = name_grid_function_root(identifier) + gf_type = _grid_function_root_type(identifier) + method_name = _get_grid_function_method_name(identifier) + return ["std::shared_ptr<{}> {}(){{".format(gf_type, method_name), " return {};".format(name), "}"] @preamble(section="postprocessing", kernel="main") -def main_define_boundary_grid_function(name, element, func): - driver_block_name = name_driver_block() - # palpo TODO - # driver_block_get_boundarygridfunction(element, func) - return "auto {} = {}.getBoundaryGridFunction();".format(name, driver_block_name) +def main_define_grid_function(name, identifier, treepath): + if len(treepath) == 0: + driver_block_get_grid_function(identifier) + driver_block_name = name_driver_block() + method_name = _get_grid_function_method_name(identifier) + return "auto {} = {}.{}();".format(name, driver_block_name, method_name) + else: + root_name = main_name_grid_function(identifier, ()) + indices = ["Dune::Indices::_{}".format(str(t)) for t in treepath] + return "auto {} = child(*{}, {});".format(name, root_name, ", ".join(i for i in indices)) -@cached -def main_name_boundary_grid_function(element, func): - # palpo TODO func rauswerfen? - assert isinstance(func, tuple) - name = "boundaryGridFunction" - main_define_boundary_grid_function(name, element, func) + +def main_name_grid_function(identifier, treepath): + name = _grid_function_root_name(identifier) + if len(treepath) > 0: + name = "{}_{}".format(name, "_".join(str(t) for t in treepath)) + main_define_grid_function(name, identifier, treepath) return name -- GitLab