/usr/lib/python2.7/dist-packages/ffc/uflacs/analysis/balancing.py is in python-ffc 2016.2.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | # -*- coding: utf-8 -*-
# Copyright (C) 2011-2016 Martin Sandve Alnæs
#
# This file is part of UFLACS.
#
# UFLACS is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# UFLACS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with UFLACS. If not, see <http://www.gnu.org/licenses/>
"""Algorithms for the representation phase of the form compilation."""
from ufl.classes import (ReferenceValue, ReferenceGrad, Grad,
CellAvg, FacetAvg,
PositiveRestricted, NegativeRestricted,
Indexed)
from ufl.corealg.multifunction import MultiFunction
from ufl.corealg.map_dag import map_expr_dag
modifier_precedence = [ReferenceValue, ReferenceGrad, Grad,
CellAvg, FacetAvg,
PositiveRestricted, NegativeRestricted,
Indexed]
modifier_precedence = { m._ufl_handler_name_: i for i, m in enumerate(modifier_precedence) }
# TODO: Move this to ufl?
# TODO: Add expr._ufl_modifier_precedence_ ? Add Terminal first and Operator last in the above list.
def balance_modified_terminal(expr):
# NB! Assuminge e.g. grad(cell_avg(expr)) does not occur,
# i.e. it is simplified to 0 immediately.
if expr._ufl_is_terminal_:
return expr
assert expr._ufl_is_terminal_modifier_
orig = expr
# Build list of modifier layers
layers = [expr]
while not expr._ufl_is_terminal_:
if not expr._ufl_is_terminal_modifier_:
import IPython; IPython.embed()
assert expr._ufl_is_terminal_modifier_
expr = expr.ufl_operands[0]
layers.append(expr)
assert layers[-1] is expr
assert expr._ufl_is_terminal_
# Apply modifiers in order
layers = sorted(layers[:-1], key=lambda e: modifier_precedence[e._ufl_handler_name_])
for op in layers:
ops = (expr,) + op.ufl_operands[1:]
expr = op._ufl_expr_reconstruct_(*ops)
# Preserve id if nothing has changed
return orig if expr == orig else expr
class BalanceModifiers(MultiFunction):
def expr(self, expr, *ops):
return expr._ufl_expr_reconstruct_(*ops)
def terminal(self, expr):
return expr
def _modifier(self, expr, *ops):
return balance_modified_terminal(expr)
reference_value = _modifier
reference_grad = _modifier
grad = _modifier
cell_avg = _modifier
facet_avg = _modifier
positive_restricted = _modifier
negative_restricted = _modifier
def balance_modifiers(expr):
mf = BalanceModifiers()
return map_expr_dag(mf, expr)
|