From 6c73820535108b40845475f89307d6a856cc6cab Mon Sep 17 00:00:00 2001
From: Marcel Koch <marcel.koch@uni-muenster.de>
Date: Wed, 12 Jul 2017 12:08:01 +0200
Subject: [PATCH] Removes micro_to_macro_index from accum_insn and introduces a
 class BlockstructuredAccumulationSpace to specialize AccumulationSpace for
 blockstructured FEM

---
 .../perftool/blockstructured/accumulation.py  | 58 +++++--------------
 python/dune/perftool/pdelab/driver.py         |  2 +-
 python/dune/perftool/pdelab/localoperator.py  | 20 ++++---
 3 files changed, 27 insertions(+), 53 deletions(-)

diff --git a/python/dune/perftool/blockstructured/accumulation.py b/python/dune/perftool/blockstructured/accumulation.py
index de08d718..30629bc5 100644
--- a/python/dune/perftool/blockstructured/accumulation.py
+++ b/python/dune/perftool/blockstructured/accumulation.py
@@ -1,47 +1,17 @@
-from dune.perftool.generation import (backend)
-from dune.perftool.pdelab.localoperator import (determine_accumulation_space,
-                                                boundary_predicates)
+from dune.perftool.pdelab.localoperator import (AccumulationSpace)
 from dune.perftool.blockstructured.tools import micro_index_to_macro_index
 
 
-@backend(interface="accum_insn", name='blockstructured')
-def generate_accumulation_instruction(visitor, accterm, measure, subdomain_id):
-    # When we do not do sumfactorization we do not split the test function
-    assert(accterm.argument.expr is None)
-
-    # Do the tree traversal to get a pymbolic expression representing this expression
-    pymbolic_expr = visitor(accterm.term)
-
-    # It may happen that an entire accumulation term vanishes. We do nothing in that case
-    if pymbolic_expr == 0:
-        return
-
-    # Collect the lfs and lfs indices for the accumulate call
-    test_lfs = determine_accumulation_space(accterm.term, 0, measure)
-
-    # In the jacobian case, also determine the space for the ansatz space
-    ansatz_lfs = determine_accumulation_space(accterm.term, 1, measure)
-
-    # Collect the lfs and lfs indices for the accumulate call
-    from dune.perftool.pdelab.argument import name_accumulation_variable
-    accumvar = name_accumulation_variable((test_lfs.get_restriction() + ansatz_lfs.get_restriction()))
-
-    predicates = boundary_predicates(accterm.term, measure, subdomain_id, visitor)
-
-    rank = 1 if ansatz_lfs.lfs is None else 2
-
-    from dune.perftool.pdelab.argument import PDELabAccumulationFunction
-    from pymbolic.primitives import Call
-    expr = Call(PDELabAccumulationFunction(accumvar, rank),
-                ((test_lfs.get_args()[0], micro_index_to_macro_index(test_lfs.get_args()[1])) + ansatz_lfs.get_args() + (pymbolic_expr,))
-                )
-
-    from dune.perftool.generation import instruction
-    quad_inames = visitor.interface.quadrature_inames()
-
-    instruction(assignees=(),
-                expression=expr,
-                forced_iname_deps=frozenset(visitor.inames).union(frozenset(quad_inames)),
-                forced_iname_deps_is_final=True,
-                predicates=predicates
-                )
\ No newline at end of file
+class BlockstructuredAccumulationSpace(AccumulationSpace):
+    def __init__(self,
+                 lfs=None,
+                 index=None,
+                 restriction=None,
+                 element=None,
+                 ):
+        AccumulationSpace.__init__(self,
+                                   lfs=lfs,
+                                   index=micro_index_to_macro_index(index),
+                                   restriction=restriction,
+                                   element=element,
+                                   )
\ No newline at end of file
diff --git a/python/dune/perftool/pdelab/driver.py b/python/dune/perftool/pdelab/driver.py
index 7f6b8b8d..a7132daf 100644
--- a/python/dune/perftool/pdelab/driver.py
+++ b/python/dune/perftool/pdelab/driver.py
@@ -306,7 +306,7 @@ def typedef_fem(expr, name):
     r = type_range()
     dim = name_dimension()
     if get_option("blockstructured"):
-        degree = expr._degree + get_option("number_of_blocks")
+        degree = get_option("number_of_blocks")
     else:
         degree = expr._degree
     if isPk(expr):
diff --git a/python/dune/perftool/pdelab/localoperator.py b/python/dune/perftool/pdelab/localoperator.py
index 53580599..40ae1230 100644
--- a/python/dune/perftool/pdelab/localoperator.py
+++ b/python/dune/perftool/pdelab/localoperator.py
@@ -249,10 +249,17 @@ def determine_accumulation_space(expr, number, measure, idims=None):
     if not isinstance(lfs, Expression):
         lfs = Variable(lfs)
 
-    return AccumulationSpace(lfs=lfs,
-                             index=lfsi,
-                             restriction=ma.restriction,
-                             )
+    if get_option("blockstructured"):
+        from dune.perftool.blockstructured.accumulation import BlockstructuredAccumulationSpace
+        return BlockstructuredAccumulationSpace(lfs=lfs,
+                                                index=lfsi,
+                                                restriction=ma.restriction,
+                                                )
+    else:
+        return AccumulationSpace(lfs=lfs,
+                                 index=lfsi,
+                                 restriction=ma.restriction,
+                                 )
 
 
 def boundary_predicates(expr, measure, subdomain_id, visitor):
@@ -409,10 +416,7 @@ def visit_integrals(integrals):
             from dune.perftool.ufl.visitor import UFL2LoopyVisitor
             visitor = UFL2LoopyVisitor(interface, measure, indexmap)
 
-            if get_option('blockstructured'):
-                get_backend(interface="accum_insn", selector=lambda: 'blockstructured')(visitor, accterm, measure, subdomain_id)
-            else:
-                get_backend(interface="accum_insn")(visitor, accterm, measure, subdomain_id)
+            get_backend(interface="accum_insn")(visitor, accterm, measure, subdomain_id)
 
 
 def generate_kernel(integrals):
-- 
GitLab