This file is indexed.

/usr/lib/python2.7/dist-packages/ffc/mixedelement.py is in python-ffc 1.6.0-2.

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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# Copyright (C) 2005-2010 Anders Logg
#
# This file is part of FFC.
#
# FFC 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.
#
# FFC 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 FFC. If not, see <http://www.gnu.org/licenses/>.
#
# Modified by Garth N. Wells, 2006-2009
# Modified by Marie E. Rognes, 2007-2010
# Modified by Kristian B. Oelgaard, 2010
# Modified by Lizao Li, 2015
#
# Last changed: 2015-04-25

# Python modules
import numpy

# FFC modules
from ffc.log import error

# UFL utils
from ufl.utils.sequences import product

class MixedElement:
    "Create a FFC mixed element from a list of FFC/FIAT elements."

    def __init__(self, elements):
        self._elements = elements
        self._entity_dofs = _combine_entity_dofs(self._elements)

    def elements(self):
        return self._elements

    def space_dimension(self):
        return sum(e.space_dimension() for e in self._elements)

    def value_shape(self):
        # Values of Tensor elements are flattened in MixedElements
        num_comps = lambda x: numpy.prod(x) if x else 1 
        return (sum(num_comps(e.value_shape()) or 1 for e in self._elements),)

    def entity_dofs(self):
        return self._entity_dofs

    def mapping(self):
        return [m for e in self._elements for m in e.mapping()]

    def dual_basis(self):
        return [L for e in self._elements for L in e.dual_basis()]

    def num_components(self):
        return sum(_num_components(e) for e in self._elements)

    def tabulate(self, order, points):
        """
        Tabulate values on mixed element by appropriately reordering
        the tabulated values for the nested elements.

        The table of values is organized as follows:

          D^a v_i[j](x_k) = table[a][i][j][k]

        where a is a multi-index (tuple) representing the derivative.
        For example, a = (1, 1) represents d/dx d/dy.
        """

        # Special case: only one element
        # NOTE: KBO: Why do we need this special case? (FFC Bug #798578)
        #       When calling tabulate() on a MixedElement one should be able to
        #       rely on getting data back which is ordered like a mixed element
        #       irrespective of the number of elements?
#        if len(self._elements) == 1:
#            return self._elements[0].tabulate(order, points)

        # Zeros for insertion into mixed table
        table_shape = (self.space_dimension(), self.num_components(), len(points))

        # Iterate over elements and fill in non-zero values
        irange = (0, 0)
        crange = (0, 0)
        mixed_table = {}
        for element in self._elements:

            # Tabulate element
            table = element.tabulate(order, points)

            # Compute range for insertion into mixed table
            irange = (irange[1], irange[1] + element.space_dimension())
            crange = (crange[1], crange[1] + _num_components(element))

            # Insert table into mixed table
            for dtuple in table.keys():

                # Insert zeros if necessary (should only happen first time)
                if not dtuple in mixed_table:
                    # NOTE: It is super important to create a new numpy.zeros
                    # instance to avoid manipulating a numpy reference in case
                    # it is created outside the loop.
                    mixed_table[dtuple] = numpy.zeros(table_shape)

                # Insert non-zero values
                if (crange[1] - crange[0]) > 1:
                    mixed_table[dtuple][irange[0]:irange[1], crange[0]:crange[1]] = numpy.reshape(table[dtuple], (irange[1] - irange[0], crange[1] - crange[0], len(points)))
                else:
                    mixed_table[dtuple][irange[0]:irange[1], crange[0]] = table[dtuple]

        return mixed_table

#--- Utility functions ---

def _combine_entity_dofs(elements):
    """
    Combine the entity_dofs from a list of elements into a combined
    entity_dof containing the information for all the elements.
    """

    # Return {} if no elements
    if not elements:
        return {}

    # Initialize entity_dofs dictionary
    entity_dofs = dict((key, {}) for key in elements[0].entity_dofs())
    for dim in elements[0].entity_dofs():
        for entity in elements[0].entity_dofs()[dim]:
            entity_dofs[dim][entity] = []

    offset = 0

    # Insert dofs from each element into the mixed entity_dof.
    for e in elements:
        dofs = e.entity_dofs()
        for dim in dofs:
            for entity in dofs[dim]:

                # Must take offset into account
                shifted_dofs = [v + offset for v in dofs[dim][entity]]

                # Insert dofs from this element into the entity_dofs
                entity_dofs[dim][entity] += shifted_dofs

        # Adjust offset
        offset += e.space_dimension()
    return entity_dofs

def _num_components(element):
    "Compute number of components for element."
    return product(element.value_shape())