From 2f567ddbfd9cb7e4f12851afd35c031aab80ec57 Mon Sep 17 00:00:00 2001
From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de>
Date: Fri, 29 Apr 2016 14:44:24 +0200
Subject: [PATCH] Symbolic jacobian is now symmetric too, (but still different)

---
 python/dune/perftool/loopy/transformer.py | 40 +++++++----------------
 python/dune/perftool/pdelab/argument.py   |  4 +--
 python/dune/perftool/pdelab/basis.py      |  4 ++-
 3 files changed, 16 insertions(+), 32 deletions(-)

diff --git a/python/dune/perftool/loopy/transformer.py b/python/dune/perftool/loopy/transformer.py
index 245882b8..0120b33f 100644
--- a/python/dune/perftool/loopy/transformer.py
+++ b/python/dune/perftool/loopy/transformer.py
@@ -165,45 +165,27 @@ def transform_accumulation_term(term, measure, subdomain_id):
     expr_tv = temporary_variable(expr_tv_name)
 
     # The data that is used to collect the arguments for the accumulate function
-    accumargs = []
-    residual_shape = {}
+    accumargs = [None] * (2 * len(test_ma))
+    residual_shape = [None] * len(test_ma)
     arg_restr = [None] * len(test_ma)
 
-    # Determine whether the inames in the jacobian case clash. This is the case, when
-    # we have a galerkin method.
-    galerkin = False
-    if len(test_ma) == 2:
-        galerkin = (test_ma[0].argexpr.element() == test_ma[1].argexpr.element())
-
-    # Generate the code for the modified arguments:
-    for arg in test_ma:
-        from dune.perftool.pdelab.argument import pymbolic_argument
-        from dune.perftool.pdelab.basis import name_lfs
-        accumargs.append(name_lfs(arg.argexpr.element()))
-
-        if galerkin and arg.argexpr.number() == 1:
-            iname = lfs_iname(arg.argexpr.element(), context="arg")
-        else:
-            iname = lfs_iname(arg.argexpr.element())
-
-        accumargs.append(iname)
-
-        # Add this iname to the set of used inames for dependencies later on
-        acc_inames = acc_inames.union(frozenset({iname}))
+    for ma in test_ma:
+        count = ma.argexpr.number()
+        lfs = name_lfs(ma.argexpr.element())
+        lfsi = lfs_iname(ma.argexpr.element(), argnumber=count)
 
-        # Determine the shape
-        residual_shape[arg.argexpr.number()] = name_lfs_bound(name_lfs(arg.argexpr.element()))
+        accumargs[2 * count] = lfs
+        accumargs[2 * count + 1] = lfsi
 
-        # Determine the restriction for later
-        arg_restr[arg.argexpr.number()] = arg.restriction
+        arg_restr[count] = ma.restriction
+        residual_shape[count] = name_lfs_bound(lfs)
 
     from dune.perftool.pdelab.argument import name_accumulation_variable
     accumvar = name_accumulation_variable(arg_restr)
 
     # The residual/the jacobian should be represented through a loopy global argument
     # TODO this seems still a bit hacky, esp. w.r.t. systems
-    shape = tuple(v for k, v in sorted(residual_shape.items(), key=lambda (k, v): k))
-    globalarg(accumvar, shape=shape)
+    globalarg(accumvar, shape=tuple(residual_shape))
 
     from dune.perftool.pdelab.quadrature import name_factor
     factor = name_factor()
diff --git a/python/dune/perftool/pdelab/argument.py b/python/dune/perftool/pdelab/argument.py
index f70f3fc9..1c2e69bf 100644
--- a/python/dune/perftool/pdelab/argument.py
+++ b/python/dune/perftool/pdelab/argument.py
@@ -36,9 +36,9 @@ def pymbolic_testfunction(ma):
     assert bool(ma.index) == ma.grad
 
     if ma.grad:
-        return Subscript(Variable(name_testfunction_gradient(ma)), (Variable(lfs_iname(ma.argexpr.element())), Variable(name_index(ma.index))))
+        return Subscript(Variable(name_testfunction_gradient(ma)), (Variable(lfs_iname(ma.argexpr.element(), argnumber=ma.argexpr.number())), Variable(name_index(ma.index))))
     else:
-        return Subscript(Variable(name_testfunction(ma)), Variable(lfs_iname(ma.argexpr.element())))
+        return Subscript(Variable(name_testfunction(ma)), Variable(lfs_iname(ma.argexpr.element(), argnumber=ma.argexpr.number())))
 
 
 @symbol
diff --git a/python/dune/perftool/pdelab/basis.py b/python/dune/perftool/pdelab/basis.py
index 0b863358..745ce9b2 100644
--- a/python/dune/perftool/pdelab/basis.py
+++ b/python/dune/perftool/pdelab/basis.py
@@ -141,7 +141,7 @@ def _lfs_iname(element, context):
     return name
 
 
-def lfs_iname(element, context=''):
+def lfs_iname(element, context='', argnumber=None):
     """ Get the iname to iterate over the local function space given by element
 
     Arguments:
@@ -155,6 +155,8 @@ def lfs_iname(element, context=''):
         a given purpose, see the 'Loops and dependencies' of the loopy docs:
         https://documen.tician.de/loopy/tutorial.html#loops-and-dependencies
     """
+    if argnumber is not None:
+        context = 'arg{}_{}'.format(argnumber, context)
     return _lfs_iname(element, context)
 
 
-- 
GitLab