From b9a473dcb4f2b2b014a603129edffca0c1d10369 Mon Sep 17 00:00:00 2001 From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de> Date: Wed, 12 Oct 2016 10:27:06 +0200 Subject: [PATCH] Fix neumann boundary poisson and symdiff --- python/dune/perftool/pdelab/localoperator.py | 90 ++++++++++--------- .../extract_accumulation_terms.py | 3 +- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py index 77cebcf0..006685f1 100644 --- a/python/dune/perftool/pdelab/localoperator.py +++ b/python/dune/perftool/pdelab/localoperator.py @@ -267,10 +267,14 @@ class AccumulationSpace(Record): return (self.restriction,) -def determine_accumulation_space(expr, number): +def determine_accumulation_space(expr, number, measure): from dune.perftool.ufl.modified_terminals import extract_modified_arguments args = extract_modified_arguments(expr, argnumber=number) + if measure == 'exterior_facet': + for ma in args: + ma.restriction = Restriction.NEGATIVE + # If this is a residual term we return a dummy object if len(args) == 0: return AccumulationSpace() @@ -308,42 +312,44 @@ def determine_accumulation_space(expr, number): ) -def boundary_predicates(): - # # Maybe wrap this instruction into a condiditional. This mostly happens with mixed boundary conditions - # if self.subdomain_id not in ['everywhere', 'otherwise']: - # # We need to reconstruct the subdomain_data parameter of the measure - # # I am *totally* confused as to why this information is not at hand anyway, - # # but conversation with Martin pointed me to dolfin.fem.assembly where this - # # is done in preprocessing with the limitation of only one possible type of - # # modified measure per integral type. - # - # # Get the original form and inspect the present measures - # from dune.perftool.generation import get_global_context_value - # original_form = get_global_context_value("formdata").original_form - # - # sd = original_form.subdomain_data() - # assert len(sd) == 1 - # subdomains, = list(sd.values()) - # domain, = list(sd.keys()) - # for k in list(subdomains.keys()): - # if subdomains[k] is None: - # del subdomains[k] - # - # # Finally extract the original subdomain_data (which needs to be present!) - # assert self.measure in subdomains - # subdomain_data = subdomains[self.measure] - # - # # Determine the name of the parameter function - # name = get_global_context_value("data").object_names[id(subdomain_data)] - # - # # Trigger the generation of code for this thing in the parameter class - # from ufl.checks import is_cellwise_constant - # cellwise_constant = is_cellwise_constant(o) - # from dune.perftool.pdelab.parameter import intersection_parameter_function - # intersection_parameter_function(name, subdomain_data, cellwise_constant, t='int') - # - # predicates = predicates.union(['{} == {}'.format(name, self.subdomain_id)]) - return frozenset([]) +def boundary_predicates(expr, measure, subdomain_id): + predicates = frozenset([]) + + if subdomain_id not in ['everywhere', 'otherwise']: + # We need to reconstruct the subdomain_data parameter of the measure + # I am *totally* confused as to why this information is not at hand anyway, + # but conversation with Martin pointed me to dolfin.fem.assembly where this + # is done in preprocessing with the limitation of only one possible type of + # modified measure per integral type. + + # Get the original form and inspect the present measures + from dune.perftool.generation import get_global_context_value + original_form = get_global_context_value("formdata").original_form + + sd = original_form.subdomain_data() + assert len(sd) == 1 + subdomains, = list(sd.values()) + domain, = list(sd.keys()) + for k in list(subdomains.keys()): + if subdomains[k] is None: + del subdomains[k] + + # Finally extract the original subdomain_data (which needs to be present!) + assert measure in subdomains + subdomain_data = subdomains[measure] + + # Determine the name of the parameter function + name = get_global_context_value("data").object_names[id(subdomain_data)] + + # Trigger the generation of code for this thing in the parameter class + from ufl.checks import is_cellwise_constant + cellwise_constant = is_cellwise_constant(expr) + from dune.perftool.pdelab.parameter import intersection_parameter_function + intersection_parameter_function(name, subdomain_data, cellwise_constant, t='int') + + predicates = predicates.union(['{} == {}'.format(name, subdomain_id)]) + + return predicates @iname @@ -355,7 +361,7 @@ def grad_iname(ma): return name -def generate_accumulation_instruction(visitor, accterm): +def generate_accumulation_instruction(visitor, accterm, measure, subdomain_id): # First we do the tree traversal to get a pymbolic expression representing this expression pymbolic_expr = visitor(accterm.term) @@ -376,14 +382,14 @@ def generate_accumulation_instruction(visitor, accterm): pymbolic_expr = Product((pymbolic_expr, test_expr)) # Collect the lfs and lfs indices for the accumulate call - test_lfs = determine_accumulation_space(accterm.argument.expr, 0) + test_lfs = determine_accumulation_space(accterm.argument.expr, 0, measure) # In the jacobian case, also determine the space for the ansatz space - ansatz_lfs = determine_accumulation_space(accterm.term, 1) + ansatz_lfs = determine_accumulation_space(accterm.term, 1, measure) from dune.perftool.pdelab.argument import name_accumulation_variable accumvar = name_accumulation_variable((ansatz_lfs.get_restriction() + test_lfs.get_restriction())) - predicates = boundary_predicates() + predicates = boundary_predicates(accterm.term, measure, subdomain_id) rank = 1 if ansatz_lfs.lfs is None else 2 @@ -447,7 +453,7 @@ def generate_kernel(integrals): # Iterate over the terms and generate a kernel for term in accterms: - generate_accumulation_instruction(visitor, term) + generate_accumulation_instruction(visitor, term, measure, subdomain_id) # Extract the information, which is needed to create a loopy kernel. # First extracting it, might be useful to alter it before kernel generation. diff --git a/python/dune/perftool/ufl/transformations/extract_accumulation_terms.py b/python/dune/perftool/ufl/transformations/extract_accumulation_terms.py index c16b19fe..3fe9d182 100644 --- a/python/dune/perftool/ufl/transformations/extract_accumulation_terms.py +++ b/python/dune/perftool/ufl/transformations/extract_accumulation_terms.py @@ -58,7 +58,8 @@ def split_into_accumulation_terms(expr): # 4) Further split according to trial function in jacobian terms if all_jacobian_args: for jac_arg in all_jacobian_args: - pass + if not isinstance(replace_expr, Zero): + ret.append(AccumulationTerm(replace_expr, test_arg)) else: if not isinstance(replace_expr, Zero): ret.append(AccumulationTerm(replace_expr, test_arg)) -- GitLab